BUG 2773 : Transition Shard to Leader state when it has no peers
[controller.git] / opendaylight / md-sal / sal-akka-raft / src / main / java / org / opendaylight / controller / cluster / raft / behaviors / AbstractRaftActorBehavior.java
index ef5f11e37aef4fe7490887a27d91caedb0e50c51..45671ea31e4c804f9993df96e3d534ceaf6e4247 100644 (file)
@@ -39,6 +39,8 @@ import scala.concurrent.duration.FiniteDuration;
  */
 public abstract class AbstractRaftActorBehavior implements RaftActorBehavior {
 
+    protected static final ElectionTimeout ELECTION_TIMEOUT = new ElectionTimeout();
+
     /**
      * Information about the RaftActor whose behavior this class represents
      */
@@ -254,7 +256,7 @@ public abstract class AbstractRaftActorBehavior implements RaftActorBehavior {
         // message is sent to itself
         electionCancel =
             context.getActorSystem().scheduler().scheduleOnce(interval,
-                context.getActor(), new ElectionTimeout(),
+                context.getActor(), ELECTION_TIMEOUT,
                 context.getActorSystem().dispatcher(), context.getActor());
     }
 
@@ -464,6 +466,11 @@ public abstract class AbstractRaftActorBehavior implements RaftActorBehavior {
         long lastApplied = context.getLastApplied();
         long tempMin = Math.min(snapshotCapturedIndex, (lastApplied > -1 ? lastApplied - 1 : -1));
 
+        if(LOG.isTraceEnabled()) {
+            LOG.trace("{}: performSnapshotWithoutCapture: snapshotCapturedIndex: {}, lastApplied: {}, tempMin: {}",
+                    logName, snapshotCapturedIndex, lastApplied, tempMin);
+        }
+
         if (tempMin > -1 && context.getReplicatedLog().isPresent(tempMin))  {
             LOG.debug("{}: fakeSnapshot purging log to {} for term {}", logName(), tempMin,
                     context.getTermInformation().getCurrentTerm());
@@ -473,7 +480,18 @@ public abstract class AbstractRaftActorBehavior implements RaftActorBehavior {
             context.getReplicatedLog().snapshotPreCommit(tempMin, entry.getTerm());
             context.getReplicatedLog().snapshotCommit();
             setReplicatedToAllIndex(tempMin);
+        } else if(tempMin > getReplicatedToAllIndex()) {
+            // It's possible a follower was lagging and an install snapshot advanced its match index past
+            // the current replicatedToAllIndex. Since the follower is now caught up we should advance the
+            // replicatedToAllIndex (to tempMin). The fact that tempMin wasn't found in the log is likely
+            // due to a previous snapshot triggered by the memory threshold exceeded, in that case we
+            // trim the log to the last applied index even if previous entries weren't replicated to all followers.
+            setReplicatedToAllIndex(tempMin);
         }
     }
 
+    protected String getId(){
+        return context.getId();
+    }
+
 }