use of org.neo4j.causalclustering.core.consensus.outcome.BatchAppendLogEntries in project neo4j by neo4j.
the class Appending method handleAppendEntriesRequest.
static void handleAppendEntriesRequest(ReadableRaftState state, Outcome outcome, RaftMessages.AppendEntries.Request request, Log log) throws IOException {
if (request.leaderTerm() < state.term()) {
RaftMessages.AppendEntries.Response appendResponse = new RaftMessages.AppendEntries.Response(state.myself(), state.term(), false, -1, state.entryLog().appendIndex());
outcome.addOutgoingMessage(new RaftMessages.Directed(request.from(), appendResponse));
return;
}
outcome.renewElectionTimeout();
outcome.setNextTerm(request.leaderTerm());
outcome.setLeader(request.from());
outcome.setLeaderCommit(request.leaderCommit());
if (!Follower.logHistoryMatches(state, request.prevLogIndex(), request.prevLogTerm(), log)) {
assert request.prevLogIndex() > -1 && request.prevLogTerm() > -1;
RaftMessages.AppendEntries.Response appendResponse = new RaftMessages.AppendEntries.Response(state.myself(), request.leaderTerm(), false, -1, state.entryLog().appendIndex());
outcome.addOutgoingMessage(new RaftMessages.Directed(request.from(), appendResponse));
return;
}
long baseIndex = request.prevLogIndex() + 1;
int offset;
/* Find possible truncation point. */
for (offset = 0; offset < request.entries().length; offset++) {
long logIndex = baseIndex + offset;
long logTerm = state.entryLog().readEntryTerm(logIndex);
if (logIndex > state.entryLog().appendIndex()) {
// entry doesn't exist because it's beyond the current log end, so we can go ahead and append
break;
} else if (logIndex < state.entryLog().prevIndex()) {
// entry doesn't exist because it's before the earliest known entry, so continue with the next one
continue;
} else if (logTerm != request.entries()[offset].term()) {
/*
* the entry's index falls within our current range and the term doesn't match what we know. We must
* truncate.
*/
if (// first, assert that we haven't committed what we are about to truncate
logIndex <= state.commitIndex()) {
throw new IllegalStateException(format("Cannot truncate entry at index %d with term %d when commit index is at %d", logIndex, logTerm, state.commitIndex()));
}
outcome.addLogCommand(new TruncateLogCommand(logIndex));
break;
}
}
if (offset < request.entries().length) {
outcome.addLogCommand(new BatchAppendLogEntries(baseIndex, offset, request.entries()));
}
Follower.commitToLogOnUpdate(state, request.prevLogIndex() + request.entries().length, request.leaderCommit(), outcome);
// this is the index of the last incoming entry
long endMatchIndex = request.prevLogIndex() + request.entries().length;
RaftMessages.AppendEntries.Response appendResponse = new RaftMessages.AppendEntries.Response(state.myself(), request.leaderTerm(), true, endMatchIndex, endMatchIndex);
outcome.addOutgoingMessage(new RaftMessages.Directed(request.from(), appendResponse));
}
Aggregations