Skip to content

Commit

Permalink
make candidateFromLeadershipTransfer atomic to avoid a race (#570)
Browse files Browse the repository at this point in the history
  • Loading branch information
dhiaayachi authored Sep 28, 2023
1 parent a3a1c10 commit 49bd61b
Show file tree
Hide file tree
Showing 2 changed files with 5 additions and 5 deletions.
2 changes: 1 addition & 1 deletion api.go
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ type Raft struct {
// candidate because the leader tries to transfer leadership. This flag is
// used in RequestVoteRequest to express that a leadership transfer is going
// on.
candidateFromLeadershipTransfer bool
candidateFromLeadershipTransfer atomic.Bool

// Stores our local server ID, used to avoid sending RPCs to ourself
localID ServerID
Expand Down
8 changes: 4 additions & 4 deletions raft.go
Original file line number Diff line number Diff line change
Expand Up @@ -293,7 +293,7 @@ func (r *Raft) runCandidate() {
// which will make other servers vote even though they have a leader already.
// It is important to reset that flag, because this priviledge could be abused
// otherwise.
defer func() { r.candidateFromLeadershipTransfer = false }()
defer func() { r.candidateFromLeadershipTransfer.Store(false) }()

electionTimeout := r.config().ElectionTimeout
electionTimer := randomTimeout(electionTimeout)
Expand Down Expand Up @@ -1390,7 +1390,7 @@ func (r *Raft) appendEntries(rpc RPC, a *AppendEntriesRequest) {

// Increase the term if we see a newer one, also transition to follower
// if we ever get an appendEntries call
if a.Term > r.getCurrentTerm() || (r.getState() != Follower && !r.candidateFromLeadershipTransfer) {
if a.Term > r.getCurrentTerm() || (r.getState() != Follower && !r.candidateFromLeadershipTransfer.Load()) {
// Ensure transition to follower
r.setState(Follower)
r.setCurrentTerm(a.Term)
Expand Down Expand Up @@ -1839,7 +1839,7 @@ func (r *Raft) electSelf() <-chan *voteResult {
Candidate: r.trans.EncodePeer(r.localID, r.localAddr),
LastLogIndex: lastIdx,
LastLogTerm: lastTerm,
LeadershipTransfer: r.candidateFromLeadershipTransfer,
LeadershipTransfer: r.candidateFromLeadershipTransfer.Load(),
}

// Construct a function to ask for a vote
Expand Down Expand Up @@ -1972,7 +1972,7 @@ func (r *Raft) initiateLeadershipTransfer(id *ServerID, address *ServerAddress)
func (r *Raft) timeoutNow(rpc RPC, req *TimeoutNowRequest) {
r.setLeader("", "")
r.setState(Candidate)
r.candidateFromLeadershipTransfer = true
r.candidateFromLeadershipTransfer.Store(true)
rpc.Respond(&TimeoutNowResponse{}, nil)
}

Expand Down

0 comments on commit 49bd61b

Please sign in to comment.