BUG-8618: refactor SyncStatusTracker state 86/58986/2
authorRobert Varga <robert.varga@pantheon.tech>
Wed, 14 Jun 2017 23:29:01 +0000 (01:29 +0200)
committerRobert Varga <robert.varga@pantheon.tech>
Thu, 15 Jun 2017 02:06:13 +0000 (04:06 +0200)
Introducing a leader target encapsulation allows us to
enfore state transitions (i.e. state is guaranteed to be
non-null when we need its bits).

This enables us to eliminate the need for a magic constant.

Change-Id: Iab7178694edc3c62032e32c4386c371630f67b6f
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/behaviors/SyncStatusTracker.java

index 8adca722a2d6a887ee37545a9b3c488f5e4c6996..08c90e32e308cecdc8391c9feff2cbc9ac21422a 100644 (file)
@@ -23,6 +23,16 @@ import org.slf4j.LoggerFactory;
  * sync if it is behind by 'syncThreshold' commits.
  */
 public class SyncStatusTracker {
+    private static final class LeaderInfo {
+        final long minimumCommitIndex;
+        final String leaderId;
+
+        LeaderInfo(final String leaderId, final long minimumCommitIndex) {
+            this.leaderId = Preconditions.checkNotNull(leaderId);
+            this.minimumCommitIndex = minimumCommitIndex;
+        }
+    }
+
     private static final Logger LOG = LoggerFactory.getLogger(SyncStatusTracker.class);
 
     private static final boolean IN_SYNC = true;
@@ -32,10 +42,8 @@ public class SyncStatusTracker {
     private final ActorRef actor;
     private final int syncThreshold;
 
-    // FIXME: what is this magic constant?
-    private long minimumExpectedIndex = -2L;
-    private String syncedLeaderId = null;
-    private boolean syncStatus = false;
+    private LeaderInfo syncTarget;
+    private boolean syncStatus;
 
     public SyncStatusTracker(final ActorRef actor, final String id, final int syncThreshold) {
         this.actor = Preconditions.checkNotNull(actor, "actor should not be null");
@@ -47,12 +55,11 @@ public class SyncStatusTracker {
     public void update(final String leaderId, final long leaderCommit, final long commitIndex) {
         Preconditions.checkNotNull(leaderId, "leaderId should not be null");
 
-        if (!leaderId.equals(syncedLeaderId)) {
-            minimumExpectedIndex = leaderCommit;
-            LOG.debug("Last sync leader {} does not match current leader {}, need to catch up to {}", syncedLeaderId,
+        if (syncTarget == null || !leaderId.equals(syncTarget.leaderId)) {
+            LOG.debug("Last sync leader does not match current leader {}, need to catch up to {}",
                 leaderId, leaderCommit);
             changeSyncStatus(NOT_IN_SYNC, true);
-            syncedLeaderId = leaderId;
+            syncTarget = new LeaderInfo(leaderId, leaderCommit);
             return;
         }
 
@@ -60,9 +67,9 @@ public class SyncStatusTracker {
         if (lag > syncThreshold) {
             LOG.debug("Lagging {} entries behind leader {}", lag, leaderId);
             changeSyncStatus(NOT_IN_SYNC, false);
-        } else if (commitIndex >= minimumExpectedIndex) {
+        } else if (commitIndex >= syncTarget.minimumCommitIndex) {
             LOG.debug("Lagging {} entries behind leader and reached {} (of expected {})", lag, leaderId, commitIndex,
-                minimumExpectedIndex);
+                syncTarget.minimumCommitIndex);
             changeSyncStatus(IN_SYNC, false);
         }
     }