X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=opendaylight%2Fmd-sal%2Fsal-akka-raft%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fcluster%2Fraft%2FFollowerLogInformationImpl.java;h=8bd0cf3d34f4639a1e053cc6c17158e469a4422f;hb=c3dd62e4b78f6d2e352d469b70be36ca7edf347f;hp=9d58288282e46770f1010f10389415ba334f4c5d;hpb=74524984b8e8625f6b8e8c791c584844d49ccf45;p=controller.git diff --git a/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/FollowerLogInformationImpl.java b/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/FollowerLogInformationImpl.java index 9d58288282..8bd0cf3d34 100644 --- a/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/FollowerLogInformationImpl.java +++ b/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/FollowerLogInformationImpl.java @@ -15,6 +15,12 @@ import javax.annotation.Nonnull; import javax.annotation.Nullable; import org.opendaylight.controller.cluster.raft.behaviors.LeaderInstallSnapshotState; +/** + * Implementation of the FollowerLogInformation interface. + * + * @author Moiz Raja + * @author Thomas Pantelis + */ public class FollowerLogInformationImpl implements FollowerLogInformation { private final Stopwatch stopwatch = Stopwatch.createUnstarted(); @@ -40,6 +46,15 @@ public class FollowerLogInformationImpl implements FollowerLogInformation { private LeaderInstallSnapshotState installSnapshotState; + private long slicedLogEntryIndex = NO_INDEX; + + /** + * Constructs an instance. + * + * @param peerInfo the associated PeerInfo of the follower. + * @param matchIndex the initial match index. + * @param context the RaftActorContext. + */ public FollowerLogInformationImpl(PeerInfo peerInfo, long matchIndex, RaftActorContext context) { this.nextIndex = context.getCommitIndex(); this.matchIndex = matchIndex; @@ -53,13 +68,18 @@ public class FollowerLogInformationImpl implements FollowerLogInformation { } @Override - public long decrNextIndex() { - return nextIndex--; + public boolean decrNextIndex() { + if (nextIndex >= 0) { + nextIndex--; + return true; + } + + return false; } @Override public boolean setNextIndex(long nextIndex) { - if(this.nextIndex != nextIndex) { + if (this.nextIndex != nextIndex) { this.nextIndex = nextIndex; return true; } @@ -68,13 +88,19 @@ public class FollowerLogInformationImpl implements FollowerLogInformation { } @Override - public long incrMatchIndex(){ + public long incrMatchIndex() { return matchIndex++; } @Override public boolean setMatchIndex(long matchIndex) { - if(this.matchIndex != matchIndex) { + // If the new match index is the index of the entry currently being sliced, then we know slicing is complete + // and the follower received the entry and responded so clear the slicedLogEntryIndex + if (isLogEntrySlicingInProgress() && slicedLogEntryIndex == matchIndex) { + slicedLogEntryIndex = NO_INDEX; + } + + if (this.matchIndex != matchIndex) { this.matchIndex = matchIndex; return true; } @@ -99,13 +125,13 @@ public class FollowerLogInformationImpl implements FollowerLogInformation { @Override public boolean isFollowerActive() { - if(peerInfo.getVotingState() == VotingState.VOTING_NOT_INITIALIZED) { + if (peerInfo.getVotingState() == VotingState.VOTING_NOT_INITIALIZED) { return false; } long elapsed = stopwatch.elapsed(TimeUnit.MILLISECONDS); - return (stopwatch.isRunning()) && - (elapsed <= context.getConfigParams().getElectionTimeOutInterval().toMillis()); + return stopwatch.isRunning() + && elapsed <= context.getConfigParams().getElectionTimeOutInterval().toMillis(); } @Override @@ -130,25 +156,23 @@ public class FollowerLogInformationImpl implements FollowerLogInformation { @Override public boolean okToReplicate() { - if(peerInfo.getVotingState() == VotingState.VOTING_NOT_INITIALIZED) { + if (peerInfo.getVotingState() == VotingState.VOTING_NOT_INITIALIZED) { return false; } // Return false if we are trying to send duplicate data before the heartbeat interval - if(getNextIndex() == lastReplicatedIndex){ - if(lastReplicatedStopwatch.elapsed(TimeUnit.MILLISECONDS) < context.getConfigParams() - .getHeartBeatInterval().toMillis()){ - return false; - } + if (getNextIndex() == lastReplicatedIndex && lastReplicatedStopwatch.elapsed(TimeUnit.MILLISECONDS) + < context.getConfigParams().getHeartBeatInterval().toMillis()) { + return false; } resetLastReplicated(); return true; } - private void resetLastReplicated(){ + private void resetLastReplicated() { lastReplicatedIndex = getNextIndex(); - if(lastReplicatedStopwatch.isRunning()){ + if (lastReplicatedStopwatch.isRunning()) { lastReplicatedStopwatch.reset(); } lastReplicatedStopwatch.start(); @@ -182,16 +206,28 @@ public class FollowerLogInformationImpl implements FollowerLogInformation { @Override public void setLeaderInstallSnapshotState(@Nonnull LeaderInstallSnapshotState state) { - if(this.installSnapshotState == null) { + if (this.installSnapshotState == null) { this.installSnapshotState = Preconditions.checkNotNull(state); } } @Override public void clearLeaderInstallSnapshotState() { + Preconditions.checkState(installSnapshotState != null); + installSnapshotState.close(); installSnapshotState = null; } + @Override + public void setSlicedLogEntryIndex(long index) { + slicedLogEntryIndex = index; + } + + @Override + public boolean isLogEntrySlicingInProgress() { + return slicedLogEntryIndex != NO_INDEX; + } + @Override public String toString() { return "FollowerLogInformationImpl [id=" + getId() + ", nextIndex=" + nextIndex + ", matchIndex=" + matchIndex