use of io.atomix.protocols.raft.protocol.AppendRequest in project atomix by atomix.
the class AbstractAppender method buildAppendEntriesRequest.
/**
* Builds a populated AppendEntries request.
*/
@SuppressWarnings("unchecked")
protected AppendRequest buildAppendEntriesRequest(RaftMemberContext member, long lastIndex) {
final RaftLogReader reader = member.getLogReader();
final Indexed<RaftLogEntry> prevEntry = reader.getCurrentEntry();
final DefaultRaftMember leader = raft.getLeader();
AppendRequest.Builder builder = AppendRequest.builder().withTerm(raft.getTerm()).withLeader(leader != null ? leader.nodeId() : null).withPrevLogIndex(prevEntry != null ? prevEntry.index() : reader.getFirstIndex() - 1).withPrevLogTerm(prevEntry != null ? prevEntry.entry().term() : 0).withCommitIndex(raft.getCommitIndex());
// Build a list of entries to send to the member.
final List<RaftLogEntry> entries = new ArrayList<>();
// Build a list of entries up to the MAX_BATCH_SIZE. Note that entries in the log may
// be null if they've been compacted and the member to which we're sending entries is just
// joining the cluster or is otherwise far behind. Null entries are simply skipped and not
// counted towards the size of the batch.
// If there exists an entry in the log with size >= MAX_BATCH_SIZE the logic ensures that
// entry will be sent in a batch of size one
int size = 0;
// Iterate through the log until the last index or the end of the log is reached.
while (reader.hasNext()) {
// Otherwise, read the next entry and add it to the batch.
Indexed<RaftLogEntry> entry = reader.next();
entries.add(entry.entry());
size += entry.size();
if (entry.index() == lastIndex || size >= MAX_BATCH_SIZE) {
break;
}
}
// Add the entries to the request builder and build the request.
return builder.withEntries(entries).build();
}
Aggregations