use of com.hazelcast.config.cp.RaftAlgorithmConfig in project hazelcast by hazelcast.
the class MembershipChangeTest method when_leaderLeaves_then_itCannotVoteForCommitOfMemberChange.
@Test
public void when_leaderLeaves_then_itCannotVoteForCommitOfMemberChange() throws ExecutionException, InterruptedException {
RaftAlgorithmConfig config = new RaftAlgorithmConfig().setLeaderHeartbeatPeriodInMillis(1000);
group = newGroup(3, config);
group.start();
RaftNodeImpl leader = group.waitUntilLeaderElected();
RaftNodeImpl[] followers = group.getNodesExcept(leader.getLocalMember());
group.dropMessagesToMember(followers[0].getLocalMember(), leader.getLocalMember(), AppendSuccessResponse.class);
leader.replicate(new ApplyRaftRunnable("val")).get();
leader.replicateMembershipChange(leader.getLocalMember(), MembershipChangeMode.REMOVE);
assertTrueAllTheTime(() -> assertEquals(1, getCommitIndex(leader)), 10);
}
use of com.hazelcast.config.cp.RaftAlgorithmConfig in project hazelcast by hazelcast.
the class MembershipChangeTest method when_newJoiningNodeFirstReceivesSnapshot_then_itInstallsSnapshot.
@Test
public void when_newJoiningNodeFirstReceivesSnapshot_then_itInstallsSnapshot() throws ExecutionException, InterruptedException {
RaftAlgorithmConfig config = new RaftAlgorithmConfig().setCommitIndexAdvanceCountToSnapshot(5);
group = newGroup(3, config);
group.start();
RaftNodeImpl leader = group.waitUntilLeaderElected();
for (int i = 0; i < 4; i++) {
leader.replicate(new ApplyRaftRunnable("val" + i)).get();
}
RaftNodeImpl newRaftNode = group.createNewRaftNode();
group.dropMessagesToMember(leader.getLocalMember(), newRaftNode.getLocalMember(), AppendRequest.class);
leader.replicateMembershipChange(newRaftNode.getLocalMember(), MembershipChangeMode.ADD).get();
assertTrueEventually(() -> assertTrue(getSnapshotEntry(leader).index() > 0));
group.resetAllRulesFrom(leader.getLocalMember());
assertTrueEventually(() -> {
assertEquals(getCommitIndex(leader), getCommitIndex(newRaftNode));
assertEquals(getLastGroupMembers(leader).members(), getLastGroupMembers(newRaftNode).members());
assertEquals(getLastGroupMembers(leader).members(), getCommittedGroupMembers(newRaftNode).members());
RaftDataService service = group.getService(newRaftNode);
assertEquals(4, service.size());
});
}
use of com.hazelcast.config.cp.RaftAlgorithmConfig in project hazelcast by hazelcast.
the class MembershipChangeTest method when_followerAppendsMultipleMembershipChangesAtOnce_then_itCommitsThemCorrectly.
@Test
public void when_followerAppendsMultipleMembershipChangesAtOnce_then_itCommitsThemCorrectly() throws ExecutionException, InterruptedException {
RaftAlgorithmConfig config = new RaftAlgorithmConfig().setLeaderHeartbeatPeriodInMillis(1000);
group = newGroup(5, config);
group.start();
RaftNodeImpl leader = group.waitUntilLeaderElected();
RaftNodeImpl[] followers = group.getNodesExcept(leader.getLocalMember());
leader.replicate(new ApplyRaftRunnable("val")).get();
assertTrueEventually(() -> {
for (RaftNodeImpl follower : followers) {
assertEquals(1L, getCommitIndex(follower));
}
});
RaftNodeImpl slowFollower = followers[0];
for (RaftNodeImpl follower : followers) {
if (follower != slowFollower) {
group.dropMessagesToMember(follower.getLocalMember(), follower.getLeader(), AppendSuccessResponse.class);
group.dropMessagesToMember(follower.getLocalMember(), follower.getLeader(), AppendFailureResponse.class);
}
}
RaftNodeImpl newRaftNode1 = group.createNewRaftNode();
group.dropMessagesToMember(leader.getLocalMember(), newRaftNode1.getLocalMember(), AppendRequest.class);
Future f1 = leader.replicateMembershipChange(newRaftNode1.getLocalMember(), MembershipChangeMode.ADD);
assertTrueEventually(() -> {
for (RaftNodeImpl follower : followers) {
assertEquals(2L, getLastLogOrSnapshotEntry(follower).index());
}
});
group.dropMessagesToMember(leader.getLocalMember(), slowFollower.getLocalMember(), AppendRequest.class);
for (RaftNodeImpl follower : followers) {
if (follower != slowFollower) {
group.allowAllMessagesToMember(follower.getLocalMember(), leader.getLeader());
}
}
f1.get();
assertTrueEventually(() -> {
for (RaftNodeImpl follower : followers) {
if (follower != slowFollower) {
assertEquals(6, getCommittedGroupMembers(follower).memberCount());
} else {
assertEquals(5, getCommittedGroupMembers(follower).memberCount());
assertEquals(6, getLastGroupMembers(follower).memberCount());
}
}
});
RaftNodeImpl newRaftNode2 = group.createNewRaftNode();
leader.replicateMembershipChange(newRaftNode2.getLocalMember(), MembershipChangeMode.ADD).get();
group.allowAllMessagesToMember(leader.getLocalMember(), slowFollower.getLocalMember());
group.allowAllMessagesToMember(slowFollower.getLocalMember(), leader.getLocalMember());
group.allowAllMessagesToMember(leader.getLocalMember(), newRaftNode1.getLocalMember());
RaftGroupMembers leaderCommittedGroupMembers = getCommittedGroupMembers(leader);
assertTrueEventually(() -> {
assertEquals(leaderCommittedGroupMembers.index(), getCommittedGroupMembers(slowFollower).index());
assertEquals(leaderCommittedGroupMembers.index(), getCommittedGroupMembers(newRaftNode1).index());
assertEquals(leaderCommittedGroupMembers.index(), getCommittedGroupMembers(newRaftNode2).index());
});
}
use of com.hazelcast.config.cp.RaftAlgorithmConfig in project hazelcast by hazelcast.
the class SnapshotTest method when_followerMissesAFewEntriesBeforeTheSnapshot_then_itCatchesUpWithoutInstallingSnapshot.
@Test
public void when_followerMissesAFewEntriesBeforeTheSnapshot_then_itCatchesUpWithoutInstallingSnapshot() throws ExecutionException, InterruptedException {
final int entryCount = 50;
// entryCount * 0.1 - 2
final int missingEntryCountOnSlowFollower = 4;
RaftAlgorithmConfig config = new RaftAlgorithmConfig().setCommitIndexAdvanceCountToSnapshot(entryCount);
group = newGroup(3, config);
group.start();
RaftNodeImpl leader = group.waitUntilLeaderElected();
RaftNodeImpl[] followers = group.getNodesExcept(leader.getLocalMember());
RaftNodeImpl slowFollower = followers[1];
for (int i = 0; i < entryCount - missingEntryCountOnSlowFollower; i++) {
leader.replicate(new ApplyRaftRunnable("val" + i)).get();
}
assertTrueEventually(() -> {
for (RaftNodeImpl follower : group.getNodesExcept(leader.getLocalMember())) {
assertEquals(entryCount - missingEntryCountOnSlowFollower, getMatchIndex(leader, follower.getLocalMember()));
}
});
group.dropMessagesToMember(leader.getLocalMember(), slowFollower.getLocalMember(), AppendRequest.class);
group.dropMessagesToMember(leader.getLocalMember(), slowFollower.getLocalMember(), InstallSnapshot.class);
for (int i = entryCount - missingEntryCountOnSlowFollower; i < entryCount; i++) {
leader.replicate(new ApplyRaftRunnable("val" + i)).get();
}
assertTrueEventually(() -> assertEquals(entryCount, getSnapshotEntry(leader).index()));
leader.replicate(new ApplyRaftRunnable("valFinal")).get();
group.allowMessagesToMember(leader.getLocalMember(), slowFollower.getLocalMember(), AppendRequest.class);
assertTrueEventually(() -> {
for (RaftNodeImpl raftNode : group.getNodes()) {
assertEquals(entryCount + 1, getCommitIndex(raftNode));
RaftDataService service = group.getService(raftNode);
assertEquals(entryCount + 1, service.size());
for (int i = 0; i < entryCount; i++) {
assertEquals(("val" + i), service.get(i + 1));
}
assertEquals("valFinal", service.get(51));
}
});
}
use of com.hazelcast.config.cp.RaftAlgorithmConfig in project hazelcast by hazelcast.
the class SnapshotTest method when_slowFollowerReceivesAppendRequestThatDoesNotFitIntoItsRaftLog_then_itTruncatesAppendRequestEntries.
@Test
public void when_slowFollowerReceivesAppendRequestThatDoesNotFitIntoItsRaftLog_then_itTruncatesAppendRequestEntries() throws ExecutionException, InterruptedException {
int appendRequestMaxEntryCount = 100;
int commitIndexAdvanceCount = 100;
int uncommittedEntryCount = 10;
RaftAlgorithmConfig config = new RaftAlgorithmConfig().setAppendRequestMaxEntryCount(appendRequestMaxEntryCount).setCommitIndexAdvanceCountToSnapshot(commitIndexAdvanceCount).setUncommittedEntryCountToRejectNewAppends(uncommittedEntryCount);
group = newGroup(5, config);
group.start();
RaftNodeImpl leader = group.waitUntilLeaderElected();
RaftNodeImpl[] followers = group.getNodesExcept(leader.getLocalMember());
RaftNodeImpl slowFollower1 = followers[0];
RaftNodeImpl slowFollower2 = followers[1];
int count = 1;
for (int i = 0; i < commitIndexAdvanceCount; i++) {
leader.replicate(new ApplyRaftRunnable("val" + (count++))).get();
}
assertTrueEventually(() -> {
for (RaftNodeImpl node : group.getNodes()) {
assertTrue(getSnapshotEntry(node).index() > 0);
}
});
group.dropMessagesToMember(leader.getLocalMember(), slowFollower1.getLocalMember(), AppendRequest.class);
for (int i = 0; i < commitIndexAdvanceCount - 1; i++) {
leader.replicate(new ApplyRaftRunnable("val" + (count++))).get();
}
assertTrueEventually(() -> assertEquals(getCommitIndex(leader), getCommitIndex(slowFollower2)));
// slowFollower2's log: [ <91 - 100 before snapshot>, <100 snapshot>, <101 - 199 committed> ]
group.dropMessagesToMember(leader.getLocalMember(), slowFollower2.getLocalMember(), AppendRequest.class);
for (int i = 0; i < commitIndexAdvanceCount / 2; i++) {
leader.replicate(new ApplyRaftRunnable("val" + (count++))).get();
}
assertTrueEventually(() -> assertTrue(getSnapshotEntry(leader).index() > commitIndexAdvanceCount));
// leader's log: [ <191 - 199 before snapshot>, <200 snapshot>, <201 - 249 committed> ]
group.allowMessagesToMember(leader.getLocalMember(), slowFollower2.getLocalMember(), AppendRequest.class);
// leader replicates 50 entries to slowFollower2 but slowFollower2 has only available capacity of 11 indices.
// so, slowFollower2 appends 11 of these 50 entries in the first AppendRequest, takes a snapshot,
// and receives another AppendRequest for the remaining entries...
assertTrueEventually(() -> {
assertEquals(getCommitIndex(leader), getCommitIndex(slowFollower2));
assertTrue(getSnapshotEntry(slowFollower2).index() > commitIndexAdvanceCount);
});
}
Aggregations