func main() {
	hostname, _ := os.Hostname()

	// Initialize the internal Raft server.
	transporter := raft.NewHTTPTransporter("/raft")
	server, _ = raft.NewServer(hostname, ".", transporter, nil, nil, "")

	// Attach the Raft server to the HTTP server.
	transporter.Install(server, http.DefaultServeMux)

	// Create a /add endpoint.
	http.HandleFunc("/add", addHandler)

	// Start both servers.
	server.Start()

	// Initialize to a cluster of one for this example.
	if server.IsLogEmpty() {
		_, err := server.Do(&raft.DefaultJoinCommand{Name: hostname})
		if err != nil {
			log.Fatal(err)
		}
	}

	// Initialize HTTP server.
	log.Fatal(http.ListenAndServe(":8000", nil))
}
예제 #2
0
파일: raft_server.go 프로젝트: hyc/influxdb
func (s *RaftServer) startRaft() error {
	log.Info("Initializing Raft Server: %s", s.config.RaftConnectionString())

	// Initialize and start Raft server.
	transporter := raft.NewHTTPTransporter("/raft")
	var err error
	s.raftServer, err = raft.NewServer(s.name, s.path, transporter, s.clusterConfig, s.clusterConfig, "")
	if err != nil {
		return err
	}

	s.raftServer.SetElectionTimeout(s.config.RaftTimeout.Duration)
	s.raftServer.LoadSnapshot() // ignore errors

	s.raftServer.AddEventListener(raft.StateChangeEventType, s.raftEventHandler)

	transporter.Install(s.raftServer, s)
	s.raftServer.Start()

	go s.CompactLog()

	if !s.raftServer.IsLogEmpty() {
		log.Info("Recovered from log")
		return nil
	}

	potentialLeaders := s.config.SeedServers

	if len(potentialLeaders) == 0 {
		log.Info("Starting as new Raft leader...")
		name := s.raftServer.Name()
		_, err := s.raftServer.Do(&InfluxJoinCommand{
			Name:                     name,
			ConnectionString:         s.config.RaftConnectionString(),
			ProtobufConnectionString: s.config.ProtobufConnectionString(),
		})

		if err != nil {
			log.Error(err)
		}
		err = s.CreateRootUser()
		return err
	}

	for {
		for _, leader := range potentialLeaders {
			log.Info("(raft:%s) Attempting to join leader: %s", s.raftServer.Name(), leader)

			if err := s.Join(leader); err == nil {
				log.Info("Joined: %s", leader)
				return nil
			}
		}

		log.Warn("Couldn't join any of the seeds, sleeping and retrying...")
		time.Sleep(100 * time.Millisecond)
	}

	return nil
}
예제 #3
0
파일: server.go 프로젝트: pombredanne/czar
// NewServer creates raft server with ØMQ transport
func NewServer(dbPath string, listenAddress string, receiveTimeout time.Duration) (*Server, error) {
	nodeName, err := getNodeName(dbPath)
	if err != nil {
		return nil, err
	}

	transporter, err := NewZmqTransporter(listenAddress, receiveTimeout)
	if err != nil {
		return nil, fmt.Errorf("error creating ZMQ transport: %v", err)
	}

	// TODO: stateMachine
	server, err := raft.NewServer(nodeName, dbPath, transporter, nil, nil, listenAddress)
	if err != nil {
		return nil, fmt.Errorf("error creating Raft server: %v", err)
	}

	// Register standard raft commands in ØMQ layer
	transporter.RegisterCommand(func() raft.Command { return &raft.DefaultJoinCommand{} })
	transporter.RegisterCommand(func() raft.Command { return &raft.DefaultLeaveCommand{} })
	transporter.RegisterCommand(func() raft.Command { return &raft.NOPCommand{} })

	return &Server{dbPath: dbPath,
		raftServer:    server,
		transport:     transporter,
		listenAddress: listenAddress,
	}, nil
}
예제 #4
0
파일: server.go 프로젝트: rboyd/raftd
// 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")
	s.raftServer, err = raft.NewServer(s.name, s.path, transporter, nil, s.db, "")
	if err != nil {
		log.Fatal(err)
	}
	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")
		}
		if err := s.Join(leader); 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.connectionString(),
		})
		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{
		Addr:    fmt.Sprintf(":%d", s.port),
		Handler: s.router,
	}

	s.router.HandleFunc("/db/{key}", s.readHandler).Methods("GET")
	s.router.HandleFunc("/db/{key}", s.writeHandler).Methods("POST")
	s.router.HandleFunc("/join", s.joinHandler).Methods("POST")

	log.Println("Listening at:", s.connectionString())

	return s.httpServer.ListenAndServe()
}
예제 #5
0
func (raftPeer *RaftPeer) ListenAndServe(router *mux.Router, httpServer raft.HTTPMuxer) error {
	var err error
	rand.Seed(time.Now().UnixNano())

	// Setup commands.
	raft.RegisterCommand(&TransactionBatchCommand{})
	raft.RegisterCommand(&SetCommand{})

	if err := os.MkdirAll(raftPeer.path, 0744); err != nil {
		log.Fatalf("Unable to create path: %v", err)
	}

	log.Printf("Initializing Raft Server: %s", raftPeer.path)

	// Initialize and start Raft server.
	transporter := raft.NewHTTPTransporter("/raft")
	//NewServer(name string, path string, transporter Transporter, stateMachine StateMachine, context interface{}, connectionString string) (*Server, error) {
	raftPeer.raftServer, err = raft.NewServer(raftPeer.name, raftPeer.path, transporter, nil, raftPeer.db, "")
	if err != nil {
		log.Fatal(err)
	}
	transporter.Install(raftPeer.raftServer, httpServer)
	raftPeer.raftServer.Start()

	// Join to leader if specified.
	if raftPeer.leaderAddress != "" {
		log.Println("Attempting to join leader:", raftPeer.leaderAddress)

		if !raftPeer.raftServer.IsLogEmpty() {
			log.Fatal("Cannot join with an existing log")
		}
		if err := raftPeer.Join(raftPeer.leaderAddress); err != nil {
			log.Fatal(err)
		}

		// Initialize the server by joining itself.
	} else if raftPeer.raftServer.IsLogEmpty() {
		log.Println("Initializing new cluster")

		_, err := raftPeer.raftServer.Do(&raft.DefaultJoinCommand{
			Name:             raftPeer.raftServer.Name(),
			ConnectionString: raftPeer.connectionString(),
		})
		if err != nil {
			log.Fatal(err)
		}

	} else {
		log.Println("Recovered from log")
	}

	router.HandleFunc("/join", raftPeer.joinHandler).Methods("POST")

	fmt.Printf("Raft listening\n")
	return nil // TODO return errors.
}
예제 #6
0
파일: raft.go 프로젝트: QLeelulu/goatherd
func (this *electServer) InitRaftServer() (err error) {
	// raft.SetLogLevel(raft.Trace)
	transporter := raft.NewHTTPTransporter("/raft", 200*time.Millisecond)
	this.raftServer, err = raft.NewServer(this.Name, this.GetDataDir(), transporter, nil, nil, "")
	if err != nil {
		return
	}
	transporter.Install(this.raftServer, this.mux)
	err = this.raftServer.Start()
	return
}
예제 #7
0
파일: server.go 프로젝트: rhtyd/hacklab
// 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)
}
예제 #8
0
func StartRaftServer(me string, path string, lead bool, peers []string) {
	log.Println("start raft")

	transporter := raft.NewHTTPTransporter("raft")

	raftserver, err := raft.NewServer(me, path, transporter, &StateMachine{}, nil)
	if err != nil {
		log.Fatal(err)
	}

	mux := http.NewServeMux()

	httpserver := &http.Server{
		Handler: mux,
		Addr:    me,
	}

	transporter.Install(raftserver, mux)

	//raftserver.Start()
	log.Println("listen and serve")
	httpserver.ListenAndServe()

}
예제 #9
0
// 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)
}
예제 #10
0
// Starts the server.
func (s *Server) ListenAndServe(primary string) error {
	var err error

	rand.Seed(int64(time.Now().Nanosecond()))

	s.primary = primary
	s.name = "name-" + s.listen

	raft.RegisterCommand(&BatchCommand{})

	// Initialize and start HTTP server.
	s.httpServer = &http.Server{
		Handler: s.router,
	}

	httpTransport := transport.NewClient().GetHTTPClient()

	//log.Printf(("Initializing Raft Server")
	transporter := NewHTTPTransporter("/raft", *httpTransport)
	s.raftServer, err = raft.NewServer(s.name, s.path, transporter, nil, s.db, "")
	if err != nil {
		log.Fatal(err)
	}
	transporter.Install(s.raftServer, s)
	s.raftServer.Start()

	s.raftServer.SetElectionTimeout(400 * time.Millisecond)

	s.raftServer.AddEventListener("addPeer", func(e raft.Event) {
		//log.Printf("Joined!")
		s.joined = true
	})

	s.raftServer.AddEventListener("leaderChange", func(e raft.Event) {
		leader := e.Value().(string)

		if leader == s.name {
			//log.Printf("Leader Changed to %v", leader)

			s.leaderNotify <- leader
		}
	})

	if primary == "" {
		cs, err := transport.Encode(s.listen)

		if err != nil {
			log.Fatal(err)
		}

		//log.Printf(("Starting as Leader")
		_, err = s.raftServer.Do(&raft.DefaultJoinCommand{
			Name:             s.raftServer.Name(),
			ConnectionString: cs,
		})
		//log.Printf(("I am Leader")

		if err != nil {
			log.Fatal(err)
		}
	} else {
		//log.Printf("Waiting 100 milliseconds to join Primary")
		time.AfterFunc(10*time.Millisecond, func() {
			maxTries := 25
			tries := 0
			for !s.joined {
				//log.Printf("Trying to Join")
				tries++
				//log.Printf("Attempting to Join")
				s.Join(primary)
				// if err != nil {
				// 	//log.Printf("Failed to join")
				// } else {
				// 	//log.Printf("Joined!")
				// 	break
				// }

				if tries > maxTries {
					log.Fatal("Could not join!")
				}

				time.Sleep(JOIN_TIMEOUT)
			}
		})
	}

	s.router.HandleFunc("/sql", s.sqlHandler).Methods("POST")
	s.router.HandleFunc("/healthcheck", s.healthcheckHandler).Methods("GET")
	s.router.HandleFunc("/join", s.joinHandler).Methods("POST")
	s.router.HandleFunc("/forward", s.forwardHandler).Methods("POST")

	// Start Unix transport
	l, err := transport.Listen(s.listen)
	if err != nil {
		log.Fatal(err)
	}

	//log.Printf(("Serving?")

	go s.healthChecker()
	go s.processQueue()
	go s.processNotifications()
	s.httpServer.Serve(l)
	return nil
}
예제 #11
0
// 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)
}
예제 #12
0
func NewRaftServer(r *mux.Router, peers []string, httpAddr string, dataDir string, topo *topology.Topology, pulseSeconds int) *RaftServer {
	s := &RaftServer{
		peers:    peers,
		httpAddr: httpAddr,
		dataDir:  dataDir,
		router:   r,
		topo:     topo,
	}

	if glog.V(4) {
		raft.SetLogLevel(2)
	}

	//注册命令以便在Do中回调
	raft.RegisterCommand(&topology.MaxVolumeIdCommand{})

	var err error

	//Creates a new HTTP transporter with the given path prefix.
	transporter := raft.NewHTTPTransporter("/cluster", 0)
	transporter.Transport.MaxIdleConnsPerHost = 1024

	//http://godoc.org/github.com/goraft/raft#RegisterCommand
	s.raftServer, err = raft.NewServer(s.httpAddr, s.dataDir, transporter, nil, topo, "")
	if err != nil {
		glog.V(0).Infoln(err)
		return nil
	}
	transporter.Install(s.raftServer, s)
	s.raftServer.SetHeartbeatInterval(1 * time.Second)
	s.raftServer.SetElectionTimeout(time.Duration(pulseSeconds) * 1150 * time.Millisecond)
	s.raftServer.Start()

	s.router.HandleFunc("/cluster/join", s.joinHandler).Methods("POST")
	s.router.HandleFunc("/cluster/status", s.statusHandler).Methods("GET")

	// Join to leader if specified.
	if len(s.peers) > 0 {
		if !s.raftServer.IsLogEmpty() {
			glog.V(0).Infoln("Starting cluster with existing logs.")
		} else {
			glog.V(0).Infoln("Joining cluster:", strings.Join(s.peers, ","))
			time.Sleep(time.Duration(rand.Intn(1000)) * time.Millisecond)
			firstJoinError := s.Join(s.peers)
			if firstJoinError != nil {
				glog.V(0).Infoln("No existing server found. Starting as leader in the new cluster.")
				_, err := s.raftServer.Do(&raft.DefaultJoinCommand{
					Name:             s.raftServer.Name(),
					ConnectionString: "http://" + s.httpAddr,
				})
				if err != nil {
					glog.V(0).Infoln(err)
					return nil
				}
			}
		}

		// Initialize the server by joining itself.
	} else if s.raftServer.IsLogEmpty() {
		glog.V(0).Infoln("Initializing new cluster")

		_, err := s.raftServer.Do(&raft.DefaultJoinCommand{
			Name:             s.raftServer.Name(),
			ConnectionString: "http://" + s.httpAddr,
		})

		if err != nil {
			glog.V(0).Infoln(err)
			return nil
		}

	} else {
		glog.V(0).Infoln("Recovered from log")
	}

	return s
}
예제 #13
0
// 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)
}
예제 #14
0
func (s *RaftServer) startRaft(potentialLeaders []string, retryUntilJoin bool) {
	log.Info("Initializing Raft Server: %s %d", s.path, s.port)

	// Initialize and start Raft server.
	transporter := raft.NewHTTPTransporter("/raft")
	var err error
	s.raftServer, err = raft.NewServer(s.name, s.path, transporter, nil, s.clusterConfig, "")
	if err != nil {
		log.Error(err)
	}

	transporter.Install(s.raftServer, s)
	s.raftServer.Start()

	if !s.raftServer.IsLogEmpty() {
		log.Info("Recovered from log")
		return
	}

	for {
		joined := false
		for _, leader := range potentialLeaders {
			log.Info("(raft:%s) Attempting to join leader: %s", s.raftServer.Name(), leader)

			if err := s.Join(leader); err == nil {
				joined = true
				log.Info("Joined: %s", leader)
				break
			}
		}

		if joined {
			break
		} else if retryUntilJoin {
			log.Warn("Couldn't join any of the seeds, sleeping and retrying...")
			time.Sleep(100 * time.Millisecond)
			continue
		}

		// couldn't join a leader so we must be the first one up
		log.Warn("Couldn't contact a leader so initializing new cluster for server on port %d", s.port)

		name := s.raftServer.Name()
		connectionString := s.connectionString()
		_, err := s.raftServer.Do(&InfluxJoinCommand{
			Name:                     name,
			ConnectionString:         connectionString,
			ProtobufConnectionString: s.config.ProtobufConnectionString(),
		})

		if err != nil {
			log.Error(err)
		}

		command := NewAddPotentialServerCommand(&ClusterServer{
			RaftName:                 name,
			RaftConnectionString:     connectionString,
			ProtobufConnectionString: s.config.ProtobufConnectionString(),
		})
		s.doOrProxyCommand(command, "add_server")
		s.CreateRootUser()
		break
	}
}
예제 #15
0
// NewRaftkv returns a new Raftkv and an error
func NewRaftkv(
	peers []string,
	kvs KVstore,
	dir string,
	Addr string,
	port int,
	transporterPrefix string,
	transporterTimeout time.Duration,
	pulse time.Duration,
) (rkv *Raftkv, err error) {
	connectionString := fmt.Sprintf("%s:%d", Addr, port)
	rkv = &Raftkv{
		peers:    peers,
		kvs:      kvs,
		dataDir:  dir,
		router:   mux.NewRouter(),
		httpAddr: connectionString,
		port:     port,
	}
	if err = os.MkdirAll(dir, 0700); err != nil {
		return nil, err
	}
	// Clear old cluster's configuration
	if len(rkv.peers) > 0 {
		if err = os.RemoveAll(path.Join(rkv.dataDir, "conf")); err != nil {
			return nil, err
		}
		if err = os.RemoveAll(path.Join(rkv.dataDir, "log")); err != nil {
			return nil, err
		}
		if err = os.RemoveAll(path.Join(rkv.dataDir, "snapshot")); err != nil {
			return nil, err
		}
	}

	transporter := raft.NewHTTPTransporter(transporterPrefix, transporterTimeout)
	rkv.server, err = raft.NewServer(connectionString, dir, transporter, nil, rkv.kvs, connectionString)
	transporter.Install(rkv.server, rkv)
	if err = rkv.server.Start(); err != nil {
		return nil, err
	}

	if pulse > 0 {
		rkv.server.SetHeartbeatInterval(pulse)
		rkv.server.SetElectionTimeout(pulse * 5)
	}

	rkv.router.HandleFunc("/raftkv_join", rkv.joinHandler)
	rkv.router.HandleFunc("/raftkv_leave", rkv.leaveHandler)
	rkv.router.HandleFunc("/raftkv_put", rkv.redirectedPut)
	rkv.router.HandleFunc("/raftkv_del", rkv.redirectedDel)
	rkv.router.HandleFunc("/raftkv_get", rkv.redirectedGet)

	if len(rkv.peers) > 0 {
		// fmt.Println(peers)
		err := rkv.Join(rkv.peers)
		if err != nil {
			logger.Println(err)
			// if cannot join clusters, joins itself
			logger.Printf("i am %s, i join myself\n", rkv.server.Name())
			_, err = rkv.server.Do(&raft.DefaultJoinCommand{
				Name:             rkv.server.Name(),
				ConnectionString: connectionString,
			})
			if err != nil {
				return nil, err
			}
		}
	} else if rkv.server.IsLogEmpty() {
		// Initialize the server by joining itself
		_, err = rkv.server.Do(&raft.DefaultJoinCommand{
			Name:             rkv.server.Name(),
			ConnectionString: connectionString,
		})
		if err != nil {
			return nil, err
		}
	}

	return rkv, nil
}
예제 #16
0
파일: server.go 프로젝트: izouxv/raftX
// Starts the server.
func (s *Server) ListenAndServe(leader string, tcpIp string) error {
	var err error

	log.Printf("Initializing Raft Server: %s", s.path)

	// Initialize and start Raft server.
	transporter := raft.NewHTTPTransporter("/raft", 200*time.Millisecond)
	s.raftServer, err = raft.NewServer(s.name, s.path, transporter, NewFsStateMachine(s.fs), s.fs, "")
	if err != nil {
		log.Fatal(err)
	}
	//s.Server.raftServer = s.raftServer

	s.raftServer.LoadSnapshot()
	s.snapshotIndex = s.raftServer.CommitIndex()

	transporter.Install(s.raftServer, s)
	s.raftServer.Start()

	leaderChangeFun := func(e raft.Event) {
		server := e.Source().(raft.Server)
		log.Printf("change: [%s] %s %v -> %v\n", server.Name(), e.Type(), e.PrevValue(), e.Value())

		if e.Type() == raft.LeaderChangeEventType {
			go func() {
				s.facade.DispatchEvent(NewEvent(kEventLeaderChanged, server, nil))
				s.facade.DispatchEvent(NewEvent(kEventUpdataLibClients, nil, nil))
			}()
		}
	}

	s.raftServer.AddEventListener(raft.StateChangeEventType, leaderChangeFun)
	s.raftServer.AddEventListener(raft.LeaderChangeEventType, leaderChangeFun)
	s.raftServer.AddEventListener(raft.TermChangeEventType, leaderChangeFun)
	s.raftServer.AddEventListener(raft.AddPeerEventType, leaderChangeFun)
	//s.raftServer.AddEventListener(raft.CommitEventType, leaderChangeFun)
	s.raftServer.AddEventListener(raft.RemovePeerEventType, leaderChangeFun)
	//s.raftServer.AddEventListener(raft.HeartbeatIntervalEventType, leaderChangeFun)

	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")
		}
		if err := s.Join(leader); err != nil {
			log.Fatal(err)
		}
	} else if s.raftServer.IsLogEmpty() {
		// Initialize the server by joining itself.

		log.Println("Initializing new cluster")
		join := raft.DefaultJoinCommand{Name: s.raftServer.Name(),
			ConnectionString: s.connectionString()}
		_, err := s.raftServer.Do(&join)
		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{
		Addr:    fmt.Sprintf(":%d", s.port),
		Handler: s.router,
	}

	s.router.HandleFunc("/db/{key}", s.readHandler).Methods("GET")
	s.router.HandleFunc("/db/{key}", s.writeHandler).Methods("POST")
	s.router.HandleFunc("/join", s.joinHandler).Methods("POST")

	log.Println("Listening at:", s.connectionString())

	s.startTcpSer(tcpIp)

	GoDone(1, func() {
		s.httpServer.ListenAndServe()
	})
	//	go func() {
	//		s.httpServer.ListenAndServe()
	//	}()
	//	return s.httpServer.ListenAndServe()
	return nil
}
예제 #17
0
파일: server.go 프로젝트: velebak/skydns
// Start starts a DNS server and blocks waiting to be killed.
func (s *Server) Start() (*sync.WaitGroup, error) {
	var err error
	log.Printf("Initializing Server. DNS Addr: %q, HTTP Addr: %q, Data Dir: %q", s.dnsAddr, s.httpAddr, s.dataDir)

	// Initialize and start Raft server.
	transporter := raft.NewHTTPTransporter("/raft")
	s.raftServer, err = raft.NewServer(s.HTTPAddr(), s.dataDir, transporter, nil, s.registry, "")
	if err != nil {
		log.Fatal(err)
	}
	transporter.Install(s.raftServer, s)
	s.raftServer.Start()

	// Join to leader if specified.
	if len(s.members) > 0 {
		log.Println("Joining cluster:", strings.Join(s.members, ","))

		if !s.raftServer.IsLogEmpty() {
			log.Fatal("Cannot join with an existing log")
		}

		if err := s.Join(s.members); err != nil {
			return nil, err
		}

		log.Println("Joined cluster")

		// Initialize the server by joining itself.
	} else if s.raftServer.IsLogEmpty() {
		log.Println("Initializing new cluster")

		_, err := s.raftServer.Do(&raft.DefaultJoinCommand{
			Name:             s.raftServer.Name(),
			ConnectionString: s.connectionString(),
		})

		if err != nil {
			log.Fatal(err)
			return nil, err
		}

	} else {
		log.Println("Recovered from log")
	}

	s.dnsTCPServer = &dns.Server{
		Addr:         s.DNSAddr(),
		Net:          "tcp",
		Handler:      s.dnsHandler,
		ReadTimeout:  s.readTimeout,
		WriteTimeout: s.writeTimeout,
	}

	s.dnsUDPServer = &dns.Server{
		Addr:         s.DNSAddr(),
		Net:          "udp",
		Handler:      s.dnsHandler,
		UDPSize:      65535,
		ReadTimeout:  s.readTimeout,
		WriteTimeout: s.writeTimeout,
	}

	s.httpServer = &http.Server{
		Addr:           s.HTTPAddr(),
		Handler:        s.router,
		ReadTimeout:    s.readTimeout,
		WriteTimeout:   s.writeTimeout,
		MaxHeaderBytes: 1 << 20,
	}

	go s.listenAndServe()

	s.waiter.Add(1)
	go s.run()

	return s.waiter, nil
}
예제 #18
0
// Create new raft test server
func newTestServer(name string, transporter raft.Transporter, dbPath string) raft.Server {
	server, _ := raft.NewServer(name, dbPath, transporter, &MockStateMachine{}, nil, "")
	return server
}