in ratis-server/src/main/java/org/apache/ratis/server/raftlog/RaftLogBase.java [175:217]
private long appendImpl(long term, TransactionContext operation) throws StateMachineException {
checkLogState();
try(AutoCloseableLock writeLock = writeLock()) {
final long nextIndex = getNextIndex();
// This is called here to guarantee strict serialization of callback executions in case
// the SM wants to attach a logic depending on ordered execution in the log commit order.
try {
operation = operation.preAppendTransaction();
} catch (StateMachineException e) {
throw e;
} catch (IOException e) {
throw new StateMachineException(memberId, e);
}
// build the log entry after calling the StateMachine
final LogEntryProto e = operation.initLogEntry(term, nextIndex);
int entrySize = e.getSerializedSize();
if (entrySize > maxBufferSize) {
throw new StateMachineException(memberId, new RaftLogIOException(
"Log entry size " + entrySize + " exceeds the max buffer limit of " + maxBufferSize));
}
appendEntry(operation.wrap(e), operation).whenComplete((returned, t) -> {
if (t != null) {
LOG.error(name + ": Failed to write log entry " + toLogEntryString(e), t);
} else if (returned != nextIndex) {
LOG.error("{}: Indices mismatched: returned index={} but nextIndex={} for log entry {}",
name, returned, nextIndex, toLogEntryString(e));
} else {
return; // no error
}
try {
close(); // close due to error
} catch (IOException ioe) {
LOG.error("Failed to close " + name, ioe);
}
});
return nextIndex;
}
}