예제 #1
0
파일: cluster.go 프로젝트: cpuguy83/drax
func (c *Cluster) start() error {
	c.store = newStore()

	cfg := raft.DefaultConfig()
	cfg.ShutdownOnRemove = false
	if c.logger != nil {
		cfg.LogOutput = c.logger
	}

	raftStream := rpc.NewStreamLayer(c.l.Addr(), byte(raftMessage), c.rpcDialer)
	raftTransport := raft.NewNetworkTransport(raftStream, 3, defaultTimeout, os.Stdout)
	peerStore := newPeerStore(c.home, raftTransport)
	c.peers = peerStore

	peers, err := peerStore.Peers()
	if err != nil {
		return err
	}
	nPeers := len(peers)
	if nPeers <= 1 && c.peerAddr == "" {
		cfg.EnableSingleNode = true
	}

	kvRaft, err := newRaft(filepath.Join(c.home, "raft"), c.addr, peerStore, (*storeFSM)(c.store), raftTransport, cfg)
	if err != nil {
		return err
	}
	c.store.r = kvRaft
	c.store.dialer = c.rpcDialer
	kvRaft.store = c.store
	kvRaft.stream = raftStream

	nodeRPCStream := rpc.NewStreamLayer(c.l.Addr(), byte(api.RPCMessage), c.rpcDialer)
	nodeRPC := &nodeRPC{nodeRPCStream, kvRaft}
	go nodeRPC.handleConns()

	clientRPCStream := rpc.NewStreamLayer(c.l.Addr(), byte(api.ClientMessage), c.rpcDialer)
	clientRPC := &clientRPC{clientRPCStream, c.store}
	go clientRPC.handleConns()

	handlers := map[byte]rpc.Handler{
		byte(raftMessage):       raftStream,
		byte(api.RPCMessage):    nodeRPCStream,
		byte(api.ClientMessage): clientRPCStream,
	}

	c.server = rpc.NewServer(c.l, handlers)
	c.r = kvRaft

	go c.store.waitLeader()
	go c.waitLeader()

	if c.peerAddr != "" && nPeers <= 1 {
		res, err := nodeRPCStream.RPC(c.peerAddr, &rpc.Request{
			Method: addNode,
			Args:   []string{c.addr},
		})
		if err != nil {
			return err
		}
		if res.Err != "" && !strings.Contains(res.Err, "peer already known") {
			return fmt.Errorf(res.Err)
		}
	}

	return nil
}
예제 #2
0
파일: client.go 프로젝트: cpuguy83/drax
// New creates a new drax Client
func New(addr string, retryTimeout time.Duration, dialer rpc.DialerFn) *Client {
	sl := rpc.NewStreamLayer(nil, byte(api.ClientMessage), dialer)
	return &Client{addr, sl, retryTimeout}
}