use of org.opendaylight.controller.cluster.raft.messages.UnInitializedFollowerSnapshotReply in project controller by opendaylight.
the class AbstractLeader method handleInstallSnapshotReply.
private void handleInstallSnapshotReply(final InstallSnapshotReply reply) {
log.debug("{}: handleInstallSnapshotReply: {}", logName(), reply);
String followerId = reply.getFollowerId();
FollowerLogInformation followerLogInformation = followerToLog.get(followerId);
if (followerLogInformation == null) {
// This can happen during AddServer if it times out.
log.error("{}: FollowerLogInformation not found for follower {} in InstallSnapshotReply", logName(), followerId);
return;
}
LeaderInstallSnapshotState installSnapshotState = followerLogInformation.getInstallSnapshotState();
if (installSnapshotState == null) {
log.error("{}: LeaderInstallSnapshotState not found for follower {} in InstallSnapshotReply", logName(), followerId);
return;
}
followerLogInformation.markFollowerActive();
if (installSnapshotState.getChunkIndex() == reply.getChunkIndex()) {
boolean wasLastChunk = false;
if (reply.isSuccess()) {
if (installSnapshotState.isLastChunk(reply.getChunkIndex())) {
// this was the last chunk reply
long followerMatchIndex = snapshotHolder.get().getLastIncludedIndex();
followerLogInformation.setMatchIndex(followerMatchIndex);
followerLogInformation.setNextIndex(followerMatchIndex + 1);
followerLogInformation.clearLeaderInstallSnapshotState();
log.info("{}: Snapshot successfully installed on follower {} (last chunk {}) - " + "matchIndex set to {}, nextIndex set to {}", logName(), followerId, reply.getChunkIndex(), followerLogInformation.getMatchIndex(), followerLogInformation.getNextIndex());
if (!anyFollowersInstallingSnapshot()) {
// once there are no pending followers receiving snapshots
// we can remove snapshot from the memory
setSnapshotHolder(null);
}
wasLastChunk = true;
if (context.getPeerInfo(followerId).getVotingState() == VotingState.VOTING_NOT_INITIALIZED) {
UnInitializedFollowerSnapshotReply unInitFollowerSnapshotSuccess = new UnInitializedFollowerSnapshotReply(followerId);
context.getActor().tell(unInitFollowerSnapshotSuccess, context.getActor());
log.debug("Sent message UnInitializedFollowerSnapshotReply to self");
}
} else {
installSnapshotState.markSendStatus(true);
}
} else {
log.warn("{}: Received failed InstallSnapshotReply - will retry: {}", logName(), reply);
installSnapshotState.markSendStatus(false);
}
if (wasLastChunk) {
if (!context.getSnapshotManager().isCapturing()) {
// Since the follower is now caught up try to purge the log.
purgeInMemoryLog();
}
} else {
ActorSelection followerActor = context.getPeerActorSelection(followerId);
if (followerActor != null) {
sendSnapshotChunk(followerActor, followerLogInformation);
}
}
} else {
log.error("{}: Chunk index {} in InstallSnapshotReply from follower {} does not match expected index {}", logName(), reply.getChunkIndex(), followerId, installSnapshotState.getChunkIndex());
if (reply.getChunkIndex() == LeaderInstallSnapshotState.INVALID_CHUNK_INDEX) {
// Since the Follower did not find this index to be valid we should reset the follower snapshot
// so that Installing the snapshot can resume from the beginning
installSnapshotState.reset();
}
}
}
use of org.opendaylight.controller.cluster.raft.messages.UnInitializedFollowerSnapshotReply in project controller by opendaylight.
the class RaftActorServerConfigurationSupportTest method testAddServerWithLeaderChangeDuringInstallSnapshot.
@Test
public void testAddServerWithLeaderChangeDuringInstallSnapshot() throws Exception {
LOG.info("testAddServerWithLeaderChangeDuringInstallSnapshot starting");
setupNewFollower();
RaftActorContext initialActorContext = new MockRaftActorContext();
TestActorRef<MockLeaderRaftActor> leaderActor = actorFactory.createTestActor(MockLeaderRaftActor.props(ImmutableMap.<String, String>of(), initialActorContext).withDispatcher(Dispatchers.DefaultDispatcherId()), actorFactory.generateActorId(LEADER_ID));
MockLeaderRaftActor leaderRaftActor = leaderActor.underlyingActor();
RaftActorContext leaderActorContext = leaderRaftActor.getRaftActorContext();
((DefaultConfigParamsImpl) leaderActorContext.getConfigParams()).setElectionTimeoutFactor(8);
ActorRef leaderCollectorActor = newLeaderCollectorActor(leaderRaftActor);
// Drop the UnInitializedFollowerSnapshotReply to delay it.
leaderRaftActor.setDropMessageOfType(UnInitializedFollowerSnapshotReply.class);
leaderActor.tell(new AddServer(NEW_SERVER_ID, newFollowerRaftActor.path().toString(), true), testKit.getRef());
final UnInitializedFollowerSnapshotReply snapshotReply = expectFirstMatching(leaderCollectorActor, UnInitializedFollowerSnapshotReply.class);
// Prevent election timeout when the leader switches to follower
((DefaultConfigParamsImpl) leaderActorContext.getConfigParams()).setElectionTimeoutFactor(100);
// Change the leader behavior to follower
leaderActor.tell(new Follower(leaderActorContext), leaderActor);
// Send the captured UnInitializedFollowerSnapshotReply - should be a no-op
leaderRaftActor.setDropMessageOfType(null);
leaderActor.tell(snapshotReply, leaderActor);
AddServerReply addServerReply = testKit.expectMsgClass(testKit.duration("5 seconds"), AddServerReply.class);
assertEquals("getStatus", ServerChangeStatus.NO_LEADER, addServerReply.getStatus());
assertEquals("Leader peers size", 0, leaderActorContext.getPeerIds().size());
LOG.info("testAddServerWithLeaderChangeDuringInstallSnapshot ending");
}
use of org.opendaylight.controller.cluster.raft.messages.UnInitializedFollowerSnapshotReply in project controller by opendaylight.
the class RaftActorServerConfigurationSupportTest method testAddServerWithInstallSnapshotTimeout.
@Test
public void testAddServerWithInstallSnapshotTimeout() throws Exception {
LOG.info("testAddServerWithInstallSnapshotTimeout starting");
setupNewFollower();
RaftActorContext initialActorContext = new MockRaftActorContext();
TestActorRef<MockLeaderRaftActor> leaderActor = actorFactory.createTestActor(MockLeaderRaftActor.props(ImmutableMap.<String, String>of(), initialActorContext).withDispatcher(Dispatchers.DefaultDispatcherId()), actorFactory.generateActorId(LEADER_ID));
MockLeaderRaftActor leaderRaftActor = leaderActor.underlyingActor();
RaftActorContext leaderActorContext = leaderRaftActor.getRaftActorContext();
((DefaultConfigParamsImpl) leaderActorContext.getConfigParams()).setElectionTimeoutFactor(1);
// Drop the InstallSnapshot message so it times out
newFollowerRaftActor.underlyingActor().setDropMessageOfType(InstallSnapshot.class);
leaderActor.tell(new AddServer(NEW_SERVER_ID, newFollowerRaftActor.path().toString(), true), testKit.getRef());
leaderActor.tell(new UnInitializedFollowerSnapshotReply("bogus"), leaderActor);
AddServerReply addServerReply = testKit.expectMsgClass(testKit.duration("5 seconds"), AddServerReply.class);
assertEquals("getStatus", ServerChangeStatus.TIMEOUT, addServerReply.getStatus());
assertEquals("Leader peers size", 0, leaderActorContext.getPeerIds().size());
assertEquals("Leader followers size", 0, ((AbstractLeader) leaderRaftActor.getCurrentBehavior()).getFollowerIds().size());
LOG.info("testAddServerWithInstallSnapshotTimeout ending");
}
Aggregations