✅ The verified answer to this question is available below. Our community-reviewed solutions help you understand the material better.
Im Raft-Paper ist die RPC Funktion RequestVote folgendermaßen definiert worden:
Im Java Code der Raft-grpc Implementierung ist die Funktion so implementiert worden:
public VoteResponse handleVoteRequest(VoteRequest request) {
log.info("Received vote request from {} for term {}", request.getCandidateId(), request.getTerm());
// Deny votes when suspended
if (suspended) {
log.info("Denying vote request - node is suspended");
return VoteResponse.newBuilder()
.setTerm(currentTerm.get())
.setVoteGranted(false)
.build();
}
if (request.getTerm() > currentTerm.get()) {
becomeFollower(request.getTerm());
}
boolean voteGranted = false;
if (request.getTerm() < currentTerm.get()) {
voteGranted = false;
logEvent(RaftEvent.EventType.VOTE_DENIED,
"Denied vote to " + request.getCandidateId() + " (stale term " + request.getTerm() + ")");
} else if (votedFor == null || votedFor.equals(request.getCandidateId())) {
int lastLogIndex = getLastLogIndex();
int lastLogTerm = getLogTermAt(lastLogIndex);
boolean logUpToDate = request.getLastLogTerm() > lastLogTerm ||
(request.getLastLogTerm() == lastLogTerm && request.getLastLogIndex() >= lastLogIndex);
if (logUpToDate) {
votedFor = request.getCandidateId();
voteGranted = true;
lastHeartbeat = System.currentTimeMillis();
// Persist vote (CRITICAL for Raft safety - must persist before responding)
persistenceService.saveState(config.getNodeId(), currentTerm.get(), votedFor);
startElectionTimer();
log.info("Voted for {}", request.getCandidateId());
logEvent(RaftEvent.EventType.VOTE_GRANTED,
"Granted vote to " + request.getCandidateId() + " for term " + request.getTerm());
} else {
logEvent(RaftEvent.EventType.VOTE_DENIED,
"Denied vote to " + request.getCandidateId() + " (log not up-to-date)");
}
} else {
logEvent(RaftEvent.EventType.VOTE_DENIED,
"Denied vote to " + request.getCandidateId() + " (already voted for " + votedFor + ")");
}
return VoteResponse.newBuilder()
.setTerm(currentTerm.get())
.setVoteGranted(voteGranted)
.build();
}
private void startElectionTimer() {
if (electionTask != null) {
electionTask.cancel(false);
}
int timeout = ThreadLocalRandom.current().nextInt(ELECTION_TIMEOUT_MIN, ELECTION_TIMEOUT_MAX);
electionTask = scheduler.schedule(this::startElection, timeout, TimeUnit.MILLISECONDS);
log.debug("Election timer started: {}ms", timeout);
}
Mit den folgenden gRPC Messages:
message VoteRequest {
int32 term = 1;
string candidateId = 2;
int32 lastLogIndex = 3;
int32 lastLogTerm = 4;
}
message VoteResponse {
int32 term = 1;
bool voteGranted = 2;
}
Welche Aussagen treffen dabei zu?