func (s *Server) joinHandler(w http.ResponseWriter, req *http.Request) { join_command := &raft.DefaultJoinCommand{} if err := json.NewDecoder(req.Body).Decode(&join_command); err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } var nodename string = join_command.NodeName() log.Println(nodename, "from", join_command.ConnectionString, "asked to join the cluster") if _, err := s.raftServer.Do(join_command); err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } log.Println(nodename, "has joined the cluster.") }
// Starts the server. func (s *Server) ListenAndServe(primary string) error { var err error = nil // Initialize and start Raft server. transporter := raft.NewHTTPTransporter("/raft") transporter.Transport.Dial = transport.UnixDialer s.raftServer, err = raft.NewServer(s.name, s.path, transporter, nil, s.sql, "") if err != nil { log.Fatal(err) } s.raftServer.SetElectionTimeout(750 * time.Millisecond) transporter.Install(s.raftServer, s) s.raftServer.Start() // Initialize and start HTTP server. s.httpServer = &http.Server{ Handler: s.router, } s.router.HandleFunc("/sql", s.sqlHandler).Methods("POST") s.router.HandleFunc("/join", s.joinHandler).Methods("POST") if primary == "" { if s.raftServer.IsLogEmpty() { _, err := s.raftServer.Do(&raft.DefaultJoinCommand{ Name: s.raftServer.Name(), ConnectionString: s.connectionString(), }) if err != nil { log.Fatal(err) } } } else { if !s.raftServer.IsLogEmpty() { log.Fatal("Cannot join with an existing log") } // namePath, _ := filepath.Abs() if err := s.Join(primary); err != nil { log.Fatal(err) } log.Println("Joined leader:", s.raftServer.Leader()) } // Start Unix transport l, err := transport.Listen(s.listen) if err != nil { log.Fatal(err) } return s.httpServer.Serve(l) }
// Joins to the leader of an existing cluster. func (s *Server) Join(leader string) error { cs, err := transport.Encode(leader) if err != nil { log.Fatal(err) } command := &raft.DefaultJoinCommand{ Name: s.raftServer.Name(), ConnectionString: s.connectionString(), } var b bytes.Buffer json.NewEncoder(&b).Encode(command) log.Println(fmt.Sprintf("%s is joining cluster %s from %s (connection string = %s)", s.name, leader, s.listen, cs)) _, err = s.client.SafePost(cs, "/join", &b) if err != nil { return err } return nil }
// Starts the server. func (s *Server) ListenAndServe(leader string) error { var err error log.Printf("Initializing Raft Server: %s", s.path) // Initialize and start Raft server. transporter := raft.NewHTTPTransporter("/raft") transporter.Transport.Dial = transport.UnixDialer 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() s.raftServer.SetHeartbeatTimeout(1 * time.Millisecond) s.raftServer.SetElectionTimeout(500 * time.Millisecond) fn := func(e raft.Event) { log.Printf("%s %v -> %v\n", e.Type(), e.PrevValue(), e.Value()) } s.raftServer.AddEventListener(raft.StateChangeEventType, fn) s.raftServer.AddEventListener(raft.LeaderChangeEventType, fn) s.raftServer.AddEventListener(raft.TermChangeEventType, fn) if leader != "" { // Join to leader if specified. log.Println("Attempting to join leader:", leader) if !s.raftServer.IsLogEmpty() { log.Fatal("Cannot join with an existing log") } //time.Sleep(1 * time.Second) if err := s.Join(leader); err != nil { log.Println("Join failed") log.Fatal(err) } log.Printf("Node %s joined leader %s" , s.connectionString(), leader) } else if s.raftServer.IsLogEmpty() { // Initialize the server by joining itself. log.Println("Initializing new cluster") cs, err := transport.Encode(s.listen) if err != nil { return err } _, err = s.raftServer.Do(&raft.DefaultJoinCommand{ Name: s.raftServer.Name(), ConnectionString: cs, }) if err != nil { log.Fatal(err) } } else { log.Println("Recovered from log") } log.Println("Initializing HTTP server") // Initialize and start HTTP server. s.httpServer = &http.Server{ Handler: s.router, } s.router.HandleFunc("/sql", s.sqlHandler).Methods("POST") s.router.HandleFunc("/join", s.joinHandler).Methods("POST") // Start Unix transport l, err := transport.Listen(s.listen) if err != nil { log.Fatal(err) } return s.httpServer.Serve(l) }
// Starts the server. func (s *Server) ListenAndServe(leader string) error { var err error // Initialize and start HTTP server. log.Println("Initializing HTTP server") s.httpServer = &http.Server{ Handler: s.router, } s.router.HandleFunc("/sql", s.sqlHandler).Methods("POST") s.router.HandleFunc("/join", s.joinHandler).Methods("POST") // Start Unix transport log.Println(s.name, "listening at", s.listen) l, err := transport.Listen(s.listen) if err != nil { log.Fatal(err) } // initialize raft transporter := raft.NewHTTPTransporter("/raft") // swap the dialer with the unix dialer that also allows unix-sockets to // be passed around transporter.Transport.Dial = transport.UnixDialer s.raftServer, err = raft.NewServer(s.name, s.path, transporter, nil, s.sql, "") if err != nil { log.Fatal(err) } transporter.Install(s.raftServer, s) // this seems to yield good results, but it's definitely not the most // empirical of the measurements s.raftServer.SetElectionTimeout(800 * time.Millisecond) s.raftServer.SetHeartbeatTimeout(150 * time.Millisecond) s.raftServer.Start() if leader != "" { // Join the leader if specified. log.Println("Attempting to join the leader:", leader) if !s.raftServer.IsLogEmpty() { log.Fatal("Cannot join with an existing log") return nil } // retry the join until we actually join the cluster // (it may take a while, until octopus sets the sockets up) for { if err := s.Join(leader); err == nil { break } log.Fatal(err) time.Sleep(10 * time.Millisecond) } log.Println("joined.") } else if s.raftServer.IsLogEmpty() { // Initialize the server by joining itself. log.Println("Initializing new cluster") _, err := s.raftServer.Do(&raft.DefaultJoinCommand{ Name: s.raftServer.Name(), ConnectionString: s.connectionString(), }) if err != nil { log.Fatal(err) } } else { log.Println("Recovered from log") } log.Println(s.name, "IS READY TO ACCEPT REQUESTS") return s.httpServer.Serve(l) }
// Starts the server. func (s *Server) ListenAndServe(leader string) error { var err error leader = strings.Replace(leader, "/", "-", -1) log.Printf("Initializing Raft Server: %s", s.path) // Initialize and start Raft server. transporter := raft.NewHTTPTransporter("/raft") transporter.Transport.Dial = transport.UnixDialer s.raftServer, err = raft.NewServer(s.name, s.path, transporter, nil, s.sql, "") if err != nil { log.Fatal(err) } s.raftServer.SetElectionTimeout(200 * time.Millisecond) // default 150ms s.raftServer.SetHeartbeatTimeout(80 * time.Millisecond) // default 50ms transporter.Install(s.raftServer, s) s.raftServer.Start() if leader != "" { // Join to leader if specified. log.Println("Attempting to join leader:", leader) if !s.raftServer.IsLogEmpty() { log.Fatal("Cannot join with an existing log") } for tries := 0; tries < 10; tries += 1 { err := s.Join(leader) if err == nil { break } log.Printf("Join attempt %d failed; sleeping", tries) time.Sleep(200 * time.Millisecond) } if 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.raftServer.Name(), ConnectionString: s.connection_string, }) if err != nil { log.Fatal(err) } } else { log.Println("Recovered from log") } // Initialize and start HTTP server. s.httpServer = &http.Server{ Handler: s.router, } s.router.HandleFunc("/sql", s.sqlHandler).Methods("POST") s.router.HandleFunc("/join", s.joinHandler).Methods("POST") s.router.HandleFunc("/forward", s.forwardHandler).Methods("GET") // Start Unix transport l, err := transport.Listen(s.listen) if err != nil { log.Fatal(err) } return s.httpServer.Serve(l) }
// Returns the connection string. func (s *Server) connectionString() string { cs, _ := transport.Encode(s.listen) log.Println("ConnectionString: " + cs) return cs }
// 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) }