///|
/// Build the RequestVote arguments this node would send while standing for
/// election in its current term.
pub fn Node::request_vote_args(self : Node) -> RequestVoteArgs {
{
term: self.current_term,
candidate_id: self.id,
last_log_index: self.last_log_index(),
last_log_term: self.last_log_term(),
}
}
///|
/// Run one round of leader election synchronously: `candidate` advances its
/// term and asks every peer for a vote, counting its own. It becomes leader on
/// a majority. If a peer reveals a higher term the candidate steps down at once
/// and the round fails. Returns whether the candidate won.
pub fn run_election(candidate : Node, peers : Array[Node]) -> Bool {
candidate.become_candidate()
let args = candidate.request_vote_args()
let mut votes = 1
for peer in peers {
let reply = peer.handle_request_vote(args)
if reply.term > candidate.current_term() {
candidate.become_follower(reply.term)
return false
}
if reply.vote_granted {
votes = votes + 1
}
}
let majority = (peers.length() + 1) / 2 + 1
if votes >= majority {
candidate.become_leader()
true
} else {
false
}
}