Browse Source

Merge pull request #8339 from javaforfun/shawnsli/check-msg-type-before-become-follower

raft: check whether it's leader PRC request when recv message with higher term
Xiang Li 8 years ago
parent
commit
6cf0fd7cb0
2 changed files with 12 additions and 3 deletions
  1. 5 3
      raft/raft.go
  2. 7 0
      raft/raft_test.go

+ 5 - 3
raft/raft.go

@@ -705,7 +705,6 @@ func (r *raft) Step(m pb.Message) error {
 	case m.Term == 0:
 	case m.Term == 0:
 		// local message
 		// local message
 	case m.Term > r.Term:
 	case m.Term > r.Term:
-		lead := m.From
 		if m.Type == pb.MsgVote || m.Type == pb.MsgPreVote {
 		if m.Type == pb.MsgVote || m.Type == pb.MsgPreVote {
 			force := bytes.Equal(m.Context, []byte(campaignTransfer))
 			force := bytes.Equal(m.Context, []byte(campaignTransfer))
 			inLease := r.checkQuorum && r.lead != None && r.electionElapsed < r.electionTimeout
 			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)
 					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
 				return nil
 			}
 			}
-			lead = None
 		}
 		}
 		switch {
 		switch {
 		case m.Type == pb.MsgPreVote:
 		case m.Type == pb.MsgPreVote:
@@ -730,7 +728,11 @@ func (r *raft) Step(m pb.Message) error {
 		default:
 		default:
 			r.logger.Infof("%x [term: %d] received a %s message with higher term from %x [term: %d]",
 			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.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:
 	case m.Term < r.Term:

+ 7 - 0
raft/raft_test.go

@@ -1755,6 +1755,13 @@ func TestFreeStuckCandidateWithCheckQuorum(t *testing.T) {
 	if c.Term != a.Term {
 	if c.Term != a.Term {
 		t.Errorf("term = %d, want %d", 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) {
 func TestNonPromotableVoterWithCheckQuorum(t *testing.T) {