// Applies Raft routes to an HTTP router for a given server. func (t *HTTPTransporter) Install(server Server, mux HTTPMuxer) { mux.HandleFunc(t.AppendEntriesPath(), transport.MakeGzipHandler(t.appendEntriesHandler(server))) mux.HandleFunc(t.RequestVotePath(), transport.MakeGzipHandler(t.requestVoteHandler(server))) mux.HandleFunc(t.SnapshotPath(), transport.MakeGzipHandler(t.snapshotHandler(server))) mux.HandleFunc(t.SnapshotRecoveryPath(), transport.MakeGzipHandler(t.snapshotRecoveryHandler(server))) }
// Starts the server. func (s *Server) ListenAndServe(primary string) error { var err error // Initialize and start HTTP server. s.httpServer = &http.Server{ Handler: s.router, } s.httpServer2 = &http.Server{ Handler: s.router, } transporter := raft.NewHTTPTransporter("/raft") s.raftServer, err = raft.NewServer(s.name, s.path, transporter, nil, s.sql, "") if err != nil { log.Fatal(err) } transporter.Install(s.raftServer, s) s.raftServer.Start() if primary != "" { log.Println("Attempting to join primary:", primary) if !s.raftServer.IsLogEmpty() { log.Fatal("Cannot join with an existing log") } if err := s.Join(primary); err != nil { log.Fatal(err) } } else if s.raftServer.IsLogEmpty() { // Initialize the server by joining itself. log.Println("Initializing new cluster") _, err := s.raftServer.Do(&raft.DefaultJoinCommand{ Name: s.name, ConnectionString: s.connectionString, }) if err != nil { log.Fatal(err) } } else { log.Println("Recovered from log") } log.Println("Initializing HTTP server") s.router.HandleFunc("/sql", transport.MakeGzipHandler(s.sqlHandler)).Methods("POST") s.router.HandleFunc("/forward", s.forwardHandler).Methods("GET") s.router.HandleFunc("/healthcheck", transport.MakeGzipHandler(s.healthcheckHandler)).Methods("GET") s.router.HandleFunc("/join", transport.MakeGzipHandler(s.joinHandler)).Methods("POST") log.Println("Listening at:", s.connectionString) // Start Unix transport l, err := transport.Listen(s.listen) for retry := 0; retry < 5 && err != nil; retry += 1 { time.Sleep(100 * time.Millisecond) l, err = transport.Listen(s.listen) } if err != nil { log.Fatal(err) } return s.httpServer.Serve(l) }