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 }
// 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} }