return{snapshot.term,false,"My raft term is newer"};
if(req.term<snapshot->term){
return{snapshot->term,false,"My raft term is newer"};
}
qdb_assert(req.term==snapshot.term);
qdb_assert(req.term==snapshot->term);
if(req.leader!=snapshot.leader){
qdb_throw("Received append entries from "<<req.leader.toString()<<", while I believe leader for term "<<snapshot.term<<" is "<<snapshot.leader.toString());
if(req.leader!=snapshot->leader){
qdb_throw("Received append entries from "<<req.leader.toString()<<", while I believe leader for term "<<snapshot->term<<" is "<<snapshot->leader.toString());
qdb_misconfig("Non-voting "<<req.candidate.toString()<<" attempted to disrupt the cluster by starting an election for term "<<req.term<<". Ignoring its request - shut down that node!");
return{snapshot.term,RaftVote::VETO};
return{snapshot->term,RaftVote::VETO};
}
qdb_warn("Non-voting "<<req.candidate.toString()<<" is requesting a vote, even though it is not a voting member of the cluster as far I know. Will still process its request, since I have no leader.");
qdb_event("Vetoing vote request from "<<req.candidate.toString()<<" because its lastIndex ("<<req.lastIndex<<") is before my log start ("<<journal.getLogStart()<<") - way too far behind me.");
// May the Gods be kind on our souls, and we never see this message in production.
qdb_throw("Candidate "<<req.candidate.toString()<<" has a log entry at "<<req.lastIndex<<" with term "<<req.lastTerm<<" while I have a COMMITTED entry with a LOWER term: "<<myLastIndexTerm<<". MAJOR CORRUPTION, DB IS ON FIRE");
}
return{snapshot.term,RaftVote::VETO};
return{snapshot->term,RaftVote::VETO};
}
if(req.lastIndex+1<=journal.getCommitIndex()){
// If the node were to ascend, it would add a leadership marker, and try
// to remove my committed req.lastIndex+1 entry as conflicting. Veto!
qdb_event("Vetoing vote request from "<<req.candidate.toString()<<" because its ascension would overwrite my committed entry with index "<<req.lastIndex+1<<" through the addition of a leadership marker.");
return{snapshot.term,RaftVote::VETO};
return{snapshot->term,RaftVote::VETO};
}
}
if(snapshot.term!=req.term){
qdb_event("Rejecting vote request from "<<req.candidate.toString()<<" because of a term mismatch: "<<snapshot.term<<" vs "<<req.term);
return{snapshot.term,RaftVote::REFUSED};
if(snapshot->term!=req.term){
qdb_event("Rejecting vote request from "<<req.candidate.toString()<<" because of a term mismatch: "<<snapshot->term<<" vs "<<req.term);
qdb_event("Rejecting vote request from "<<req.candidate.toString()<<" since I've voted already in this term ("<<snapshot.term<<") for "<<snapshot.votedFor.toString());
qdb_event("Rejecting vote request from "<<req.candidate.toString()<<" since I've voted already in this term ("<<snapshot->term<<") for "<<snapshot->votedFor.toString());
return{snapshot->term,RaftVote::REFUSED};
}
LogIndexmyLastIndex=journal.getLogSize()-1;
RaftTermmyLastTerm;
if(!journal.fetch(myLastIndex,myLastTerm).ok()){
qdb_critical("Error when reading journal entry "<<myLastIndex<<" when processing request vote.");
return{snapshot.term,RaftVote::REFUSED};
return{snapshot->term,RaftVote::REFUSED};
}
if(req.lastTerm<myLastTerm){
qdb_event("Rejecting vote request from "<<req.candidate.toString()<<" since my log is more up-to-date, based on last term: "<<myLastIndex<<","<<myLastTerm<<" vs "<<req.lastIndex<<","<<req.lastTerm);
qdb_event("Rejecting vote request from "<<req.candidate.toString()<<" since my log is more up-to-date, based on last index: "<<myLastIndex<<","<<myLastTerm<<" vs "<<req.lastIndex<<","<<req.lastTerm);
return{snapshot.term,RaftVote::REFUSED};
return{snapshot->term,RaftVote::REFUSED};
}
// grant vote
if(!state.grantVote(req.term,req.candidate)){
qdb_warn("RaftState rejected the vote request from "<<req.candidate.toString()<<" and term "<<req.term<<" - probably benign race condition?");