dev-urandom / graft

Guys have you heard of this consensus protocol called raft?
12 stars 6 forks source link

Should voters increment their term even if the candidate's log is out of date? #14

Open benmills opened 11 years ago

benmills commented 11 years ago

I think that the voter should always set it's term to the candidate's term unless the voter has a higher term. If we don't do that we would need to have the candidate decrement it's term if it looses the election or you could have the cluster in an inconsistent state regarding the current term.

Let me try to layout a scenario to illustrate this:

candidate := NewServer()
voter := NewServer()

// Both servers start with term 0
candidate.Term
//=> 0

voter.Term
//=> 0

// candidate increments it's term
candidate.StartElection()
candidate.Term
//=> 1

Now let's say that voter's log is ahead of the candidate causing it to respond with VoteGranted: false. The candidate now loses the election and steps down. Because of this line in voter.go:

if server.Term < message.Term && server.logUpToDate(message) {

The voter will only execute this code before it finishes it's vote:

} else {                                 
        return VoteResponseMessage{      
                Term:        server.Term,
                VoteGranted: false,      
        }, nil                           
}                                        

The most important point here is the voter doesn't change it's term. That means the election ends and the voter has a term 0 and the candidate (now a follower) has a term 1. I think in the grand scheme of things this won't matter because eventually a leader will be elected with a term higher than 0 and the voter will "jump" to that term, but I think it's unintentional.

I think we should have the voter set it's term to the candidate's term so that, in a debugging scenario, it's clear that it participated in the election for that term regardless of it's outcome.