mirror of
https://github.com/gogrlx/nats-server.git
synced 2026-04-02 11:48:43 -07:00
Do not fail to start with small cluster sizes.
Short ciruit full wait for leaders if we were a leadership xfer of preferred. Signed-off-by: Derek Collison <derek@nats.io>
This commit is contained in:
@@ -158,6 +158,9 @@ type raft struct {
|
||||
sq *sendq
|
||||
aesub *subscription
|
||||
|
||||
// Are we doing a leadership transfer.
|
||||
lxfer bool
|
||||
|
||||
// For holding term and vote and peerstate to be written.
|
||||
wtv []byte
|
||||
wps []byte
|
||||
@@ -204,7 +207,7 @@ type lps struct {
|
||||
}
|
||||
|
||||
const (
|
||||
minElectionTimeout = 1500 * time.Millisecond
|
||||
minElectionTimeout = 1000 * time.Millisecond
|
||||
maxElectionTimeout = 5 * minElectionTimeout
|
||||
minCampaignTimeout = 100 * time.Millisecond
|
||||
maxCampaignTimeout = 4 * minCampaignTimeout
|
||||
@@ -317,8 +320,8 @@ func (s *Server) startRaftNode(cfg *RaftConfig) (RaftNode, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if ps == nil || (len(ps.knownPeers) < 2 && ps.clusterSize < 2) {
|
||||
return nil, errors.New("raft: cluster too small")
|
||||
if ps == nil {
|
||||
return nil, errors.New("raft: no peerstate")
|
||||
}
|
||||
|
||||
n := &raft{
|
||||
@@ -1073,6 +1076,7 @@ func (n *raft) campaign() error {
|
||||
if n.state == Leader {
|
||||
return errAlreadyLeader
|
||||
}
|
||||
n.lxfer = true
|
||||
n.resetElect(randCampaignTimeout())
|
||||
return nil
|
||||
}
|
||||
@@ -2084,7 +2088,7 @@ func (n *raft) runAsCandidate() {
|
||||
if n.wonElection(votes) {
|
||||
// TODO If this server was also leader in n.term-1, then we could skip the timer as well.
|
||||
// This would be ok as we'd be guaranteed to have the latest history.
|
||||
if len(n.peers) == votes {
|
||||
if len(n.peers) == votes || n.lxfer {
|
||||
// Become LEADER if we have won and gotten a quorum with everyone
|
||||
n.switchToLeader()
|
||||
return
|
||||
@@ -3023,6 +3027,7 @@ func (n *raft) switchToFollower(leader string) {
|
||||
return
|
||||
}
|
||||
n.debug("Switching to follower")
|
||||
n.lxfer = false
|
||||
n.leader = leader
|
||||
n.switchState(Follower)
|
||||
}
|
||||
@@ -3035,11 +3040,14 @@ func (n *raft) switchToCandidate() {
|
||||
}
|
||||
if n.state != Candidate {
|
||||
n.debug("Switching to candidate")
|
||||
} else if n.lostQuorumLocked() {
|
||||
if time.Since(n.llqrt) > 20*time.Second {
|
||||
// We signal to the upper layers such that can alert on quorum lost.
|
||||
n.updateLeadChange(false)
|
||||
n.llqrt = time.Now()
|
||||
} else {
|
||||
n.lxfer = false
|
||||
if n.lostQuorumLocked() {
|
||||
if time.Since(n.llqrt) > 20*time.Second {
|
||||
// We signal to the upper layers such that can alert on quorum lost.
|
||||
n.updateLeadChange(false)
|
||||
n.llqrt = time.Now()
|
||||
}
|
||||
}
|
||||
}
|
||||
// Increment the term.
|
||||
@@ -3057,5 +3065,6 @@ func (n *raft) switchToLeader() {
|
||||
}
|
||||
n.debug("Switching to leader")
|
||||
n.leader = n.id
|
||||
n.lxfer = false
|
||||
n.switchState(Leader)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user