// Open starts the raft consensus and opens the store. func (s *Store) Open() error { s.mu.Lock() defer s.mu.Unlock() // Require bind address & advertise address. if s.BindAddress == "" { return ErrBindAddressRequired } else if s.Advertise == nil { return ErrAdvertiseRequired } // Create root directory. if err := os.MkdirAll(s.path, 0777); err != nil { return err } // Create raft configuration. config := raft.DefaultConfig() config.HeartbeatTimeout = s.HeartbeatTimeout config.ElectionTimeout = s.ElectionTimeout config.LeaderLeaseTimeout = s.LeaderLeaseTimeout config.CommitTimeout = s.CommitTimeout config.LogOutput = s.LogOutput config.EnableSingleNode = s.EnableSingleNode // Begin listening to TCP port. trans, err := raft.NewTCPTransport(s.BindAddress, s.Advertise, 3, 10*time.Second, os.Stderr) if err != nil { return fmt.Errorf("opening tcp transport: %s", err) } s.transport = trans // Setup storage layers. s.peerStore = raft.NewJSONPeers(s.path, s.transport) stableStore, err := raftboltdb.NewBoltStore(filepath.Join(s.path, "raft.db")) if err != nil { return fmt.Errorf("stable store: %s", err) } s.stableStore = stableStore // Create the snapshot store. ss, err := raft.NewFileSnapshotStore(s.path, 2, os.Stderr) if err != nil { return fmt.Errorf("snapshot store: %s", err) } // Create raft log. r, err := raft.NewRaft(config, s, stableStore, stableStore, ss, s.peerStore, s.transport) if err != nil { return fmt.Errorf("raft: %s", err) } s.raft = r return nil }
// Open starts the raft consensus and opens the store. func (s *Store) Open() error { s.mu.Lock() defer s.mu.Unlock() // Set up logging. s.logger = log.New(s.LogOutput, "[discoverd] ", log.LstdFlags) // Require listener & advertise address. if s.Listener == nil { return ErrListenerRequired } else if s.Advertise == nil { return ErrAdvertiseRequired } // Create root directory. if err := os.MkdirAll(s.path, 0777); err != nil { return err } // Create raft configuration. config := raft.DefaultConfig() config.HeartbeatTimeout = s.HeartbeatTimeout config.ElectionTimeout = s.ElectionTimeout config.LeaderLeaseTimeout = s.LeaderLeaseTimeout config.CommitTimeout = s.CommitTimeout config.LogOutput = s.LogOutput config.EnableSingleNode = s.EnableSingleNode // Create multiplexing transport layer. raftLayer := newRaftLayer(s.Listener, s.Advertise) // Begin listening to TCP port. s.transport = raft.NewNetworkTransport(raftLayer, 3, 10*time.Second, os.Stderr) // Setup storage layers. s.peerStore = raft.NewJSONPeers(s.path, s.transport) stableStore, err := raftboltdb.NewBoltStore(filepath.Join(s.path, "raft.db")) if err != nil { return fmt.Errorf("stable store: %s", err) } s.stableStore = stableStore // Wrap the store in a LogCache to improve performance cacheStore, err := raft.NewLogCache(512, stableStore) if err != nil { stableStore.Close() return fmt.Errorf("log cache: %s", err) } // Create the snapshot store. ss, err := raft.NewFileSnapshotStore(s.path, 2, os.Stderr) if err != nil { return fmt.Errorf("snapshot store: %s", err) } // Create raft log. r, err := raft.NewRaft(config, s, cacheStore, stableStore, ss, s.peerStore, s.transport) if err != nil { return fmt.Errorf("raft: %s", err) } s.raft = r // Start goroutine to monitor leadership changes. s.wg.Add(1) go s.monitorLeaderCh() // Start goroutine to check for instance expiry. s.wg.Add(1) go s.expirer() return nil }