diff --git a/raft/raft.go b/raft/raft.go index f408a326b..10d268df1 100644 --- a/raft/raft.go +++ b/raft/raft.go @@ -705,7 +705,6 @@ func (r *raft) Step(m pb.Message) error { case m.Term == 0: // local message case m.Term > r.Term: - lead := m.From if m.Type == pb.MsgVote || m.Type == pb.MsgPreVote { force := bytes.Equal(m.Context, []byte(campaignTransfer)) inLease := r.checkQuorum && r.lead != None && r.electionElapsed < r.electionTimeout @@ -716,7 +715,6 @@ func (r *raft) Step(m pb.Message) error { r.id, r.raftLog.lastTerm(), r.raftLog.lastIndex(), r.Vote, m.Type, m.From, m.LogTerm, m.Index, r.Term, r.electionTimeout-r.electionElapsed) return nil } - lead = None } switch { case m.Type == pb.MsgPreVote: @@ -730,7 +728,11 @@ func (r *raft) Step(m pb.Message) error { default: r.logger.Infof("%x [term: %d] received a %s message with higher term from %x [term: %d]", r.id, r.Term, m.Type, m.From, m.Term) - r.becomeFollower(m.Term, lead) + if m.Type == pb.MsgApp || m.Type == pb.MsgHeartbeat || m.Type == pb.MsgSnap { + r.becomeFollower(m.Term, m.From) + } else { + r.becomeFollower(m.Term, None) + } } case m.Term < r.Term: diff --git a/raft/raft_test.go b/raft/raft_test.go index 529b8a807..be7694673 100644 --- a/raft/raft_test.go +++ b/raft/raft_test.go @@ -1755,6 +1755,13 @@ func TestFreeStuckCandidateWithCheckQuorum(t *testing.T) { if c.Term != a.Term { t.Errorf("term = %d, want %d", c.Term, a.Term) } + + // Vote again, should become leader this time + nt.send(pb.Message{From: 3, To: 3, Type: pb.MsgHup}) + + if c.state != StateLeader { + t.Errorf("peer 3 state: %s, want %s", c.state, StateLeader) + } } func TestNonPromotableVoterWithCheckQuorum(t *testing.T) {