Search in sources :

Example 31 with ApplyRaftRunnable

use of com.hazelcast.cp.internal.raft.impl.dataservice.ApplyRaftRunnable in project hazelcast by hazelcast.

the class LocalRaftTest method when_leaderStaysInMinorityDuringSplit_then_itCannotCommitNewEntries.

@Test
public void when_leaderStaysInMinorityDuringSplit_then_itCannotCommitNewEntries() throws ExecutionException, InterruptedException {
    group = newGroup(3, newRaftConfigWithNoSnapshotting(100));
    group.start();
    RaftNodeImpl leader = group.waitUntilLeaderElected();
    leader.replicate(new ApplyRaftRunnable("val1")).get();
    assertTrueEventually(() -> {
        for (RaftNodeImpl raftNode : group.getNodes()) {
            assertEquals(1, getCommitIndex(raftNode));
        }
    });
    RaftNodeImpl[] followers = group.getNodesExcept(leader.getLocalMember());
    group.split(leader.getLocalMember());
    assertTrueEventually(() -> {
        for (RaftNodeImpl raftNode : followers) {
            RaftEndpoint leaderEndpoint = getLeaderMember(raftNode);
            assertNotNull(leaderEndpoint);
            assertNotEquals(leader.getLocalMember(), leaderEndpoint);
        }
    });
    List<InternalCompletableFuture> isolatedFutures = new ArrayList<>();
    for (int i = 0; i < 10; i++) {
        isolatedFutures.add(leader.replicate(new ApplyRaftRunnable("isolated" + i)));
    }
    RaftNodeImpl newLeader = group.getNode(getLeaderMember(followers[0]));
    for (int i = 0; i < 10; i++) {
        newLeader.replicate(new ApplyRaftRunnable("valNew" + i)).get();
    }
    assertTrueEventually(() -> {
        for (RaftNodeImpl raftNode : followers) {
            assertEquals(11, getCommitIndex(raftNode));
        }
    });
    group.merge();
    RaftNodeImpl finalLeader = group.waitUntilLeaderElected();
    assertNotEquals(leader.getLocalMember(), finalLeader.getLocalMember());
    for (InternalCompletableFuture f : isolatedFutures) {
        try {
            f.joinInternal();
            fail();
        } catch (LeaderDemotedException ignored) {
        }
    }
    assertTrueEventually(() -> {
        for (RaftNodeImpl raftNode : followers) {
            RaftDataService service = group.getService(raftNode);
            assertEquals(11, service.size());
            assertEquals("val1", service.get(1));
            for (int i = 0; i < 10; i++) {
                assertEquals(("valNew" + i), service.get(i + 2));
            }
        }
    });
}
Also used : LeaderDemotedException(com.hazelcast.cp.exception.LeaderDemotedException) ApplyRaftRunnable(com.hazelcast.cp.internal.raft.impl.dataservice.ApplyRaftRunnable) RaftDataService(com.hazelcast.cp.internal.raft.impl.dataservice.RaftDataService) InternalCompletableFuture(com.hazelcast.spi.impl.InternalCompletableFuture) ArrayList(java.util.ArrayList) ParallelJVMTest(com.hazelcast.test.annotation.ParallelJVMTest) QuickTest(com.hazelcast.test.annotation.QuickTest) Test(org.junit.Test)

Example 32 with ApplyRaftRunnable

use of com.hazelcast.cp.internal.raft.impl.dataservice.ApplyRaftRunnable in project hazelcast by hazelcast.

the class LocalRaftTest method when_leaderCrashes_then_theFollowerWithLongestLogBecomesLeader.

@Test
public void when_leaderCrashes_then_theFollowerWithLongestLogBecomesLeader() throws Exception {
    group = newGroup(4);
    group.start();
    RaftNodeImpl leader = group.waitUntilLeaderElected();
    leader.replicate(new ApplyRaftRunnable("val1")).get();
    RaftNodeImpl[] followers = group.getNodesExcept(leader.getLocalMember());
    RaftNodeImpl nextLeader = followers[0];
    long commitIndex = getCommitIndex(leader);
    assertTrueEventually(() -> {
        for (RaftNodeImpl raftNode : group.getNodes()) {
            assertEquals(commitIndex, getCommitIndex(raftNode));
        }
    });
    for (int i = 1; i < followers.length; i++) {
        group.dropMessagesToMember(leader.getLocalMember(), followers[i].getLocalMember(), AppendRequest.class);
    }
    leader.replicate(new ApplyRaftRunnable("val2"));
    assertTrueEventually(() -> assertTrue(getLastLogOrSnapshotEntry(nextLeader).index() > commitIndex));
    assertTrueAllTheTime(() -> {
        for (RaftNodeImpl raftNode : group.getNodes()) {
            assertEquals(commitIndex, getCommitIndex(raftNode));
        }
    }, 10);
    group.terminateNode(leader.getLocalMember());
    assertTrueEventually(() -> {
        for (RaftNodeImpl raftNode : followers) {
            assertEquals(nextLeader.getLocalMember(), getLeaderMember(raftNode));
        }
    });
    assertTrueEventually(() -> {
        for (RaftNodeImpl raftNode : followers) {
            assertEquals(commitIndex, getCommitIndex(raftNode));
            assertTrue(getLastLogOrSnapshotEntry(raftNode).index() > commitIndex);
            RaftDataService service = group.getService(raftNode);
            assertEquals(1, service.size());
            assertEquals("val1", service.get(1));
        // val2 not committed yet
        }
    });
}
Also used : ApplyRaftRunnable(com.hazelcast.cp.internal.raft.impl.dataservice.ApplyRaftRunnable) RaftDataService(com.hazelcast.cp.internal.raft.impl.dataservice.RaftDataService) ParallelJVMTest(com.hazelcast.test.annotation.ParallelJVMTest) QuickTest(com.hazelcast.test.annotation.QuickTest) Test(org.junit.Test)

Example 33 with ApplyRaftRunnable

use of com.hazelcast.cp.internal.raft.impl.dataservice.ApplyRaftRunnable in project hazelcast by hazelcast.

the class PersistenceTest method when_followerIsRestarted_then_itRestoresItsRaftStateWithSnapshot.

@Test
public void when_followerIsRestarted_then_itRestoresItsRaftStateWithSnapshot() throws ExecutionException, InterruptedException {
    final int committedEntryCountToSnapshot = 50;
    RaftAlgorithmConfig config = new RaftAlgorithmConfig().setCommitIndexAdvanceCountToSnapshot(committedEntryCountToSnapshot);
    group = new LocalRaftGroupBuilder(3, config).setAppendNopEntryOnLeaderElection(true).setRaftStateStoreFactory(RAFT_STATE_STORE_FACTORY).build();
    group.start();
    final RaftNodeImpl leader = group.waitUntilLeaderElected();
    for (int i = 0; i <= committedEntryCountToSnapshot; i++) {
        leader.replicate(new ApplyRaftRunnable("val" + i)).get();
    }
    assertTrueEventually(() -> {
        for (RaftNodeImpl node : group.getNodes()) {
            assertTrue(getSnapshotEntry(node).index() > 0);
        }
    });
    RaftNodeImpl terminatedFollower = group.getAnyFollowerNode();
    RaftEndpoint terminatedEndpoint = terminatedFollower.getLocalMember();
    InMemoryRaftStateStore stateStore = getRaftStateStore(terminatedFollower);
    RestoredRaftState terminatedState = stateStore.toRestoredRaftState();
    group.terminateNode(terminatedEndpoint);
    leader.replicate(new ApplyRaftRunnable("val" + (committedEntryCountToSnapshot + 1))).get();
    final RaftNodeImpl restartedNode = group.createNewRaftNode(terminatedState, stateStore);
    assertEquals(new ArrayList<>(getCommittedGroupMembers(leader).members()), new ArrayList<>(getCommittedGroupMembers(restartedNode).members()));
    assertEquals(new ArrayList<>(getLastGroupMembers(leader).members()), new ArrayList<>(getLastGroupMembers(restartedNode).members()));
    assertTrueEventually(() -> {
        assertEquals(leader.getLocalMember(), restartedNode.getLeader());
        assertEquals(getTerm(leader), getTerm(restartedNode));
        assertEquals(getCommitIndex(leader), getCommitIndex(restartedNode));
        assertEquals(getLastApplied(leader), getLastApplied(restartedNode));
        RaftDataService service = group.getService(restartedNode);
        Object[] values = service.valuesArray();
        assertThat(values, arrayWithSize(committedEntryCountToSnapshot + 2));
        for (int i = 0; i <= committedEntryCountToSnapshot + 1; i++) {
            assertEquals("val" + i, values[i]);
        }
    });
}
Also used : RaftAlgorithmConfig(com.hazelcast.config.cp.RaftAlgorithmConfig) RestoredRaftState(com.hazelcast.cp.internal.raft.impl.persistence.RestoredRaftState) InMemoryRaftStateStore(com.hazelcast.cp.internal.raft.impl.testing.InMemoryRaftStateStore) ApplyRaftRunnable(com.hazelcast.cp.internal.raft.impl.dataservice.ApplyRaftRunnable) RaftDataService(com.hazelcast.cp.internal.raft.impl.dataservice.RaftDataService) LocalRaftGroupBuilder(com.hazelcast.cp.internal.raft.impl.testing.LocalRaftGroup.LocalRaftGroupBuilder) ParallelJVMTest(com.hazelcast.test.annotation.ParallelJVMTest) QuickTest(com.hazelcast.test.annotation.QuickTest) Test(org.junit.Test)

Example 34 with ApplyRaftRunnable

use of com.hazelcast.cp.internal.raft.impl.dataservice.ApplyRaftRunnable in project hazelcast by hazelcast.

the class PersistenceTest method when_leaderIsRestarted_then_itBecomesLeaderAndAppliesPreviouslyCommittedMemberListViaSnapshot.

@Test
public void when_leaderIsRestarted_then_itBecomesLeaderAndAppliesPreviouslyCommittedMemberListViaSnapshot() throws ExecutionException, InterruptedException {
    int committedEntryCountToSnapshot = 50;
    RaftAlgorithmConfig config = new RaftAlgorithmConfig().setCommitIndexAdvanceCountToSnapshot(committedEntryCountToSnapshot);
    group = new LocalRaftGroupBuilder(3, config).setAppendNopEntryOnLeaderElection(true).setRaftStateStoreFactory(RAFT_STATE_STORE_FACTORY).build();
    group.start();
    RaftNodeImpl leader = group.waitUntilLeaderElected();
    RaftNodeImpl[] followers = group.getNodesExcept(leader.getLocalMember());
    RaftNodeImpl removedFollower = followers[0];
    final RaftNodeImpl runningFollower = followers[1];
    group.terminateNode(removedFollower.getLocalMember());
    leader.replicate(new ApplyRaftRunnable("val")).get();
    leader.replicateMembershipChange(removedFollower.getLocalMember(), REMOVE).get();
    while (getSnapshotEntry(leader).index() == 0) {
        leader.replicate(new ApplyRaftRunnable("val")).get();
    }
    RaftEndpoint terminatedEndpoint = leader.getLocalMember();
    InMemoryRaftStateStore stateStore = getRaftStateStore(leader);
    RestoredRaftState terminatedState = stateStore.toRestoredRaftState();
    // Block voting between followers
    // to avoid a leader election before leader restarts.
    blockVotingBetweenFollowers();
    group.terminateNode(terminatedEndpoint);
    RaftNodeImpl restartedNode = group.createNewRaftNode(terminatedState, stateStore);
    RaftNodeImpl newLeader = group.waitUntilLeaderElected();
    assertSame(restartedNode, newLeader);
    assertTrueEventually(() -> {
        assertEquals(getCommitIndex(runningFollower), getCommitIndex(restartedNode));
        assertEquals(new ArrayList<>(getCommittedGroupMembers(runningFollower).members()), new ArrayList<>(getCommittedGroupMembers(restartedNode).members()));
        assertEquals(new ArrayList<>(getLastGroupMembers(runningFollower).members()), new ArrayList<>(getLastGroupMembers(restartedNode).members()));
    });
}
Also used : RaftAlgorithmConfig(com.hazelcast.config.cp.RaftAlgorithmConfig) RestoredRaftState(com.hazelcast.cp.internal.raft.impl.persistence.RestoredRaftState) InMemoryRaftStateStore(com.hazelcast.cp.internal.raft.impl.testing.InMemoryRaftStateStore) ApplyRaftRunnable(com.hazelcast.cp.internal.raft.impl.dataservice.ApplyRaftRunnable) LocalRaftGroupBuilder(com.hazelcast.cp.internal.raft.impl.testing.LocalRaftGroup.LocalRaftGroupBuilder) ParallelJVMTest(com.hazelcast.test.annotation.ParallelJVMTest) QuickTest(com.hazelcast.test.annotation.QuickTest) Test(org.junit.Test)

Example 35 with ApplyRaftRunnable

use of com.hazelcast.cp.internal.raft.impl.dataservice.ApplyRaftRunnable in project hazelcast by hazelcast.

the class PersistenceTest method when_leaderIsRestarted_then_itRestoresItsRaftStateAndBecomesLeader.

@Test
public void when_leaderIsRestarted_then_itRestoresItsRaftStateAndBecomesLeader() throws ExecutionException, InterruptedException {
    group = new LocalRaftGroupBuilder(3).setRaftStateStoreFactory(RAFT_STATE_STORE_FACTORY).setAppendNopEntryOnLeaderElection(true).build();
    group.start();
    RaftNodeImpl leader = group.waitUntilLeaderElected();
    final int count = 10;
    for (int i = 0; i < count; i++) {
        leader.replicate(new ApplyRaftRunnable("val" + i)).get();
    }
    final int term = getTerm(leader);
    final long commitIndex = getCommitIndex(leader);
    RaftEndpoint terminatedEndpoint = leader.getLocalMember();
    InMemoryRaftStateStore stateStore = getRaftStateStore(leader);
    RestoredRaftState terminatedState = stateStore.toRestoredRaftState();
    // Block voting between followers
    // to avoid a leader election before leader restarts.
    blockVotingBetweenFollowers();
    group.terminateNode(terminatedEndpoint);
    RaftNodeImpl restartedNode = group.createNewRaftNode(terminatedState, stateStore);
    RaftNodeImpl newLeader = group.waitUntilLeaderElected();
    assertSame(newLeader, restartedNode);
    assertTrueEventually(() -> {
        assertTrue(getTerm(restartedNode) > term);
        assertEquals(commitIndex + 1, getCommitIndex(restartedNode));
        RaftDataService service = group.getService(restartedNode);
        Object[] values = service.valuesArray();
        assertThat(values, arrayWithSize(count));
        for (int i = 0; i < count; i++) {
            assertEquals("val" + i, values[i]);
        }
    });
}
Also used : RestoredRaftState(com.hazelcast.cp.internal.raft.impl.persistence.RestoredRaftState) InMemoryRaftStateStore(com.hazelcast.cp.internal.raft.impl.testing.InMemoryRaftStateStore) ApplyRaftRunnable(com.hazelcast.cp.internal.raft.impl.dataservice.ApplyRaftRunnable) RaftDataService(com.hazelcast.cp.internal.raft.impl.dataservice.RaftDataService) LocalRaftGroupBuilder(com.hazelcast.cp.internal.raft.impl.testing.LocalRaftGroup.LocalRaftGroupBuilder) ParallelJVMTest(com.hazelcast.test.annotation.ParallelJVMTest) QuickTest(com.hazelcast.test.annotation.QuickTest) Test(org.junit.Test)

Aggregations

ApplyRaftRunnable (com.hazelcast.cp.internal.raft.impl.dataservice.ApplyRaftRunnable)55 ParallelJVMTest (com.hazelcast.test.annotation.ParallelJVMTest)50 QuickTest (com.hazelcast.test.annotation.QuickTest)50 Test (org.junit.Test)50 RaftDataService (com.hazelcast.cp.internal.raft.impl.dataservice.RaftDataService)31 RaftAlgorithmConfig (com.hazelcast.config.cp.RaftAlgorithmConfig)23 LocalRaftGroupBuilder (com.hazelcast.cp.internal.raft.impl.testing.LocalRaftGroup.LocalRaftGroupBuilder)15 InternalCompletableFuture (com.hazelcast.spi.impl.InternalCompletableFuture)15 RestoredRaftState (com.hazelcast.cp.internal.raft.impl.persistence.RestoredRaftState)14 InMemoryRaftStateStore (com.hazelcast.cp.internal.raft.impl.testing.InMemoryRaftStateStore)10 Future (java.util.concurrent.Future)8 ArrayList (java.util.ArrayList)5 QueryRaftRunnable (com.hazelcast.cp.internal.raft.impl.dataservice.QueryRaftRunnable)4 LogEntry (com.hazelcast.cp.internal.raft.impl.log.LogEntry)4 RaftGroupMembers (com.hazelcast.cp.internal.raft.impl.state.RaftGroupMembers)4 StaleAppendRequestException (com.hazelcast.cp.exception.StaleAppendRequestException)3 CannotReplicateException (com.hazelcast.cp.exception.CannotReplicateException)2 LeaderDemotedException (com.hazelcast.cp.exception.LeaderDemotedException)2 DestroyRaftGroupCmd (com.hazelcast.cp.internal.raft.command.DestroyRaftGroupCmd)2 RaftUtil.getSnapshotEntry (com.hazelcast.cp.internal.raft.impl.RaftUtil.getSnapshotEntry)2