protected SnapshotInfo shouldInstallSnapshot() { final long logStartIndex = raftLog.getStartIndex(); // we should install snapshot if the follower needs to catch up and: // 1. there is no local log entry but there is snapshot // 2. or the follower's next index is smaller than the log start index if (follower.getNextIndex() < raftLog.getNextIndex()) { SnapshotInfo snapshot = server.getState().getLatestSnapshot(); if (follower.getNextIndex() < logStartIndex || (logStartIndex == INVALID_LOG_INDEX && snapshot != null)) { return snapshot; } } return null; }
/** Should the leader send appendEntries RPC to this follower? */ protected boolean shouldSendRequest() { return shouldAppendEntries(follower.getNextIndex()) || shouldHeartbeat(); }
protected SnapshotInfo shouldInstallSnapshot() { final long logStartIndex = raftLog.getStartIndex(); // we should install snapshot if the follower needs to catch up and: // 1. there is no local log entry but there is snapshot // 2. or the follower's next index is smaller than the log start index if (follower.getNextIndex() < raftLog.getNextIndex()) { SnapshotInfo snapshot = server.getState().getLatestSnapshot(); if (follower.getNextIndex() < logStartIndex || (logStartIndex == INVALID_LOG_INDEX && snapshot != null)) { return snapshot; } } return null; }
/** Should the leader send appendEntries RPC to this follower? */ protected boolean shouldSendRequest() { return shouldAppendEntries(follower.getNextIndex()) || shouldHeartbeat(); }
@Override public String toString() { return name + "(c" + getCommitIndex() + ",m" + getMatchIndex() + ",n" + getNextIndex() + ", attendVote=" + attendVote + ", lastRpcSendTime=" + lastRpcSendTime.get().elapsedTimeMs() + ", lastRpcResponseTime=" + lastRpcResponseTime.get().elapsedTimeMs() + ")"; }
long[] getFollowerNextIndices() { return senders.stream().mapToLong(s -> s.getFollower().getNextIndex()).toArray(); }
private TermIndex getPrevious() { TermIndex previous = raftLog.getTermIndex(follower.getNextIndex() - 1); if (previous == null) { // if previous is null, nextIndex must be equal to the log start // index (otherwise we will install snapshot). Preconditions.assertTrue(follower.getNextIndex() == raftLog.getStartIndex(), "%s: follower's next index %s, local log start index %s", this, follower.getNextIndex(), raftLog.getStartIndex()); SnapshotInfo snapshot = server.getState().getLatestSnapshot(); previous = snapshot == null ? null : snapshot.getTermIndex(); } return previous; }
private TermIndex getPrevious() { TermIndex previous = raftLog.getTermIndex(follower.getNextIndex() - 1); if (previous == null) { // if previous is null, nextIndex must be equal to the log start // index (otherwise we will install snapshot). Preconditions.assertTrue(follower.getNextIndex() == raftLog.getStartIndex(), "%s: follower's next index %s, local log start index %s", this, follower.getNextIndex(), raftLog.getStartIndex()); SnapshotInfo snapshot = server.getState().getLatestSnapshot(); previous = snapshot == null ? null : snapshot.getTermIndex(); } return previous; }
long[] getFollowerNextIndices() { return senders.stream().mapToLong(s -> s.getFollower().getNextIndex()).toArray(); }
LOG.info("{}: follower {}'s next index is {}," + " log's start index is {}, need to install snapshot", server.getId(), follower.getPeer(), follower.getNextIndex(), raftLog.getStartIndex()); if (isAppenderRunning() && !shouldAppendEntries(follower.getNextIndex())) { final long waitTime = getHeartbeatRemainingTime(); if (waitTime > 0) {
LOG.info("{}: follower {}'s next index is {}," + " log's start index is {}, need to install snapshot", server.getId(), follower.getPeer(), follower.getNextIndex(), raftLog.getStartIndex()); follower.getNextIndex() + buffer.getPendingEntryNum())) { final long waitTime = getHeartbeatRemainingTime(); if (waitTime > 0) {
switch (reply.getResult()) { case SUCCESS: final long oldNextIndex = follower.getNextIndex(); final long nextIndex = reply.getNextIndex(); if (nextIndex < oldNextIndex) {
switch (reply.getResult()) { case SUCCESS: final long oldNextIndex = follower.getNextIndex(); final long nextIndex = reply.getNextIndex(); if (nextIndex < oldNextIndex) {
protected AppendEntriesRequestProto createRequest(long callId) throws RaftLogIOException { final TermIndex previous = getPrevious(); final long leaderNext = raftLog.getNextIndex(); long next = follower.getNextIndex() + buffer.getPendingEntryNum(); final boolean toSend; if (leaderNext == next && !buffer.isEmpty()) { // no new entries, then send out the entries in the buffer toSend = true; } else if (leaderNext > next) { boolean hasSpace = true; for(; hasSpace && leaderNext > next;) { hasSpace = buffer.addEntry(raftLog.get(next++)); } // buffer is full or batch sending is disabled, send out a request toSend = !hasSpace || !batchSending; } else { toSend = false; } if (toSend || shouldHeartbeat()) { return buffer.getAppendRequest(previous, callId); } return null; }
protected AppendEntriesRequestProto createRequest(long callId) throws RaftLogIOException { final TermIndex previous = getPrevious(); final long heartbeatRemainingMs = getHeartbeatRemainingTime(); if (heartbeatRemainingMs <= 0L) { return leaderState.newAppendEntriesRequestProto( getFollowerId(), previous, Collections.emptyList(), !follower.isAttendingVote(), callId); } Preconditions.assertTrue(buffer.isEmpty(), () -> "buffer has " + buffer.getNumElements() + " elements."); final long leaderNext = raftLog.getNextIndex(); for (long next = follower.getNextIndex(); leaderNext > next; ) { if (!buffer.offer(raftLog.getEntryWithData(next++))) { break; } } if (buffer.isEmpty()) { return null; } final List<LogEntryProto> protos = buffer.pollList(heartbeatRemainingMs, EntryWithData::getEntry, (entry, time, exception) -> LOG.warn(this + ": Failed get " + entry + " in " + time, exception)); buffer.clear(); return leaderState.newAppendEntriesRequestProto( getFollowerId(), previous, protos, !follower.isAttendingVote(), callId); }
private void installSnapshot(SnapshotInfo snapshot) { LOG.info("{}: follower {}'s next index is {}," + " log's start index is {}, need to install snapshot", server.getId(), follower.getPeer(), follower.getNextIndex(), raftLog.getStartIndex());
Assert.assertEquals(followerMatchIndex + 1, logAppender.getFollower().getNextIndex()); }, 10, HUNDRED_MILLIS, "assertRaftLog-" + logAppender.getFollower(), LOG)));
Assert.assertEquals(logAppender.getFollower().getNextIndex(), index); });