From: Tom Pantelis Date: Tue, 15 Mar 2016 23:51:58 +0000 (-0400) Subject: Bug 5460: Fix snaphots on follower X-Git-Tag: release/boron~310 X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?p=controller.git;a=commitdiff_plain;h=a605375505d33b6cc12e766d839fd8bccf8bb69b Bug 5460: Fix snaphots on follower Added a callback to the appendAndPersist call in Follower to call captureSnapshotIfReady. Added checks in ReplicationAndSnapshotsIntegrationTest to verify the followers snapshot along with the leader. Change-Id: Ie71f1b16152541d069f9d005ba669cb1e5771dd1 Signed-off-by: Tom Pantelis --- diff --git a/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/behaviors/Follower.java b/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/behaviors/Follower.java index afb8f29e70..33ed3357d8 100644 --- a/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/behaviors/Follower.java +++ b/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/behaviors/Follower.java @@ -9,6 +9,7 @@ package org.opendaylight.controller.cluster.raft.behaviors; import akka.actor.ActorRef; +import akka.japi.Procedure; import com.google.common.annotations.VisibleForTesting; import java.util.ArrayList; import org.opendaylight.controller.cluster.raft.RaftActorContext; @@ -37,12 +38,18 @@ import org.opendaylight.controller.cluster.raft.messages.RequestVoteReply; * */ public class Follower extends AbstractRaftActorBehavior { - - private SnapshotTracker snapshotTracker = null; + private static final int SYNC_THRESHOLD = 10; private final SyncStatusTracker initialSyncStatusTracker; - private static final int SYNC_THRESHOLD = 10; + private final Procedure appendAndPersistCallback = new Procedure() { + @Override + public void apply(ReplicatedLogEntry logEntry) { + context.getReplicatedLog().captureSnapshotIfReady(logEntry); + } + }; + + private SnapshotTracker snapshotTracker = null; public Follower(RaftActorContext context) { this(context, null, (short)-1); @@ -195,7 +202,7 @@ public class Follower extends AbstractRaftActorBehavior { LOG.debug("{}: Append entry to log {}", logName(), entry.getData()); - context.getReplicatedLog().appendAndPersist(entry); + context.getReplicatedLog().appendAndPersist(entry, appendAndPersistCallback); if(entry.getData() instanceof ServerConfigurationPayload) { context.updatePeerIds((ServerConfigurationPayload)entry.getData()); diff --git a/opendaylight/md-sal/sal-akka-raft/src/test/java/org/opendaylight/controller/cluster/raft/ReplicationAndSnapshotsIntegrationTest.java b/opendaylight/md-sal/sal-akka-raft/src/test/java/org/opendaylight/controller/cluster/raft/ReplicationAndSnapshotsIntegrationTest.java index 949889a9ce..6334173cc6 100644 --- a/opendaylight/md-sal/sal-akka-raft/src/test/java/org/opendaylight/controller/cluster/raft/ReplicationAndSnapshotsIntegrationTest.java +++ b/opendaylight/md-sal/sal-akka-raft/src/test/java/org/opendaylight/controller/cluster/raft/ReplicationAndSnapshotsIntegrationTest.java @@ -62,11 +62,13 @@ public class ReplicationAndSnapshotsIntegrationTest extends AbstractRaftActorInt // Create the leader and 2 follower actors and verify initial syncing of the followers after leader // persistence recovery. + DefaultConfigParamsImpl followerConfigParams = newFollowerConfigParams(); + followerConfigParams.setSnapshotBatchCount(snapshotBatchCount); follower1Actor = newTestRaftActor(follower1Id, ImmutableMap.of(leaderId, testActorPath(leaderId), - follower2Id, testActorPath(follower2Id)), newFollowerConfigParams()); + follower2Id, testActorPath(follower2Id)), followerConfigParams); follower2Actor = newTestRaftActor(follower2Id, ImmutableMap.of(leaderId, testActorPath(leaderId), - follower1Id, testActorPath(follower1Id)), newFollowerConfigParams()); + follower1Id, testActorPath(follower1Id)), followerConfigParams); peerAddresses = ImmutableMap.builder(). put(follower1Id, follower1Actor.path().toString()). @@ -226,6 +228,18 @@ public class ReplicationAndSnapshotsIntegrationTest extends AbstractRaftActorInt assertEquals("Leader last applied", 3, leaderContext.getLastApplied()); assertEquals("Leader replicatedToAllIndex", 2, leader.getReplicatedToAllIndex()); + // The followers should also snapshot so verify. + + MessageCollectorActor.expectFirstMatching(follower1CollectorActor, SaveSnapshotSuccess.class); + persistedSnapshots = InMemorySnapshotStore.getSnapshots(follower1Id, Snapshot.class); + assertEquals("Persisted snapshots size", 1, persistedSnapshots.size()); + verifySnapshot("Persisted", persistedSnapshots.get(0), initialTerm, 2, currentTerm, 3); + unAppliedEntry = persistedSnapshots.get(0).getUnAppliedEntries(); + assertEquals("Persisted Snapshot getUnAppliedEntries size", 1, unAppliedEntry.size()); + verifyReplicatedLogEntry(unAppliedEntry.get(0), currentTerm, 3, payload3); + + MessageCollectorActor.expectFirstMatching(follower2CollectorActor, SaveSnapshotSuccess.class); + MessageCollectorActor.clearMessages(leaderCollectorActor); MessageCollectorActor.clearMessages(follower1CollectorActor); MessageCollectorActor.clearMessages(follower2CollectorActor);