Search in sources :

Example 1 with LogEntry

use of com.hazelcast.cp.internal.raft.impl.log.LogEntry in project hazelcast by hazelcast.

the class SemaphoreAdvancedTest method testNewRaftGroupMemberSchedulesTimeoutsWithSnapshot.

@Test
public void testNewRaftGroupMemberSchedulesTimeoutsWithSnapshot() throws ExecutionException, InterruptedException {
    semaphore.init(1);
    spawn(() -> {
        try {
            semaphore.tryAcquire(2, 10, MINUTES);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    });
    CPGroupId groupId = getGroupId();
    assertTrueEventually(() -> {
        HazelcastInstance leader = leaderInstanceOf(groupId);
        SemaphoreService service = getNodeEngineImpl(leader).getService(SemaphoreService.SERVICE_NAME);
        SemaphoreRegistry registry = service.getRegistryOrNull(groupId);
        assertFalse(registry.getWaitTimeouts().isEmpty());
    });
    for (int i = 0; i < LOG_ENTRY_COUNT_TO_SNAPSHOT; i++) {
        semaphore.acquire();
        semaphore.release();
    }
    assertTrueEventually(() -> {
        for (HazelcastInstance instance : instances) {
            RaftNodeImpl raftNode = getRaftNode(instance, groupId);
            assertNotNull(raftNode);
            LogEntry snapshotEntry = getSnapshotEntry(raftNode);
            assertTrue(snapshotEntry.index() > 0);
            List<RestoreSnapshotOp> ops = (List<RestoreSnapshotOp>) snapshotEntry.operation();
            for (RestoreSnapshotOp op : ops) {
                if (op.getServiceName().equals(SemaphoreService.SERVICE_NAME)) {
                    ResourceRegistry registry = (ResourceRegistry) op.getSnapshot();
                    assertFalse(registry.getWaitTimeouts().isEmpty());
                    return;
                }
            }
            fail();
        }
    });
    instances[1].shutdown();
    HazelcastInstance newInstance = factory.newHazelcastInstance(createConfig(groupSize, groupSize));
    newInstance.getCPSubsystem().getCPSubsystemManagementService().promoteToCPMember().toCompletableFuture().get();
    assertTrueEventually(() -> {
        SemaphoreService service = getNodeEngineImpl(newInstance).getService(SemaphoreService.SERVICE_NAME);
        SemaphoreRegistry registry = service.getRegistryOrNull(groupId);
        assertNotNull(registry);
        assertFalse(registry.getWaitTimeouts().isEmpty());
        assertEquals(1, registry.availablePermits(objectName));
    });
}
Also used : CPGroupId(com.hazelcast.cp.CPGroupId) HazelcastInstance(com.hazelcast.core.HazelcastInstance) RaftNodeImpl(com.hazelcast.cp.internal.raft.impl.RaftNodeImpl) RestoreSnapshotOp(com.hazelcast.cp.internal.raftop.snapshot.RestoreSnapshotOp) List(java.util.List) ResourceRegistry(com.hazelcast.cp.internal.datastructures.spi.blocking.ResourceRegistry) LogEntry(com.hazelcast.cp.internal.raft.impl.log.LogEntry) ParallelJVMTest(com.hazelcast.test.annotation.ParallelJVMTest) QuickTest(com.hazelcast.test.annotation.QuickTest) Test(org.junit.Test)

Example 2 with LogEntry

use of com.hazelcast.cp.internal.raft.impl.log.LogEntry in project hazelcast by hazelcast.

the class ReplicateTask method run.

@Override
public void run() {
    try {
        if (!verifyRaftNodeStatus()) {
            return;
        }
        RaftState state = raftNode.state();
        if (state.role() != LEADER) {
            resultFuture.completeExceptionally(new NotLeaderException(raftNode.getGroupId(), raftNode.getLocalMember(), state.leader()));
            return;
        }
        if (!raftNode.canReplicateNewEntry(operation)) {
            resultFuture.completeExceptionally(new CannotReplicateException(raftNode.getLocalMember()));
            return;
        }
        if (logger.isFineEnabled()) {
            logger.fine("Replicating: " + operation + " in term: " + state.term());
        }
        RaftLog log = state.log();
        if (!log.checkAvailableCapacity(1)) {
            resultFuture.completeExceptionally(new IllegalStateException("Not enough capacity in RaftLog!"));
            return;
        }
        long newEntryLogIndex = log.lastLogOrSnapshotIndex() + 1;
        raftNode.registerFuture(newEntryLogIndex, resultFuture);
        log.appendEntries(new LogEntry(state.term(), newEntryLogIndex, operation));
        preApplyRaftGroupCmd(newEntryLogIndex, operation);
        raftNode.broadcastAppendRequest();
    } catch (Throwable t) {
        logger.severe(operation + " could not be replicated to leader: " + raftNode.getLocalMember(), t);
        RaftEndpoint leader = raftNode.getLeader();
        UUID leaderUuid = leader != null ? leader.getUuid() : null;
        resultFuture.completeExceptionally(new CPSubsystemException("Internal failure", t, leaderUuid));
    }
}
Also used : NotLeaderException(com.hazelcast.cp.exception.NotLeaderException) RaftState(com.hazelcast.cp.internal.raft.impl.state.RaftState) RaftEndpoint(com.hazelcast.cp.internal.raft.impl.RaftEndpoint) CannotReplicateException(com.hazelcast.cp.exception.CannotReplicateException) UUID(java.util.UUID) CPSubsystemException(com.hazelcast.cp.exception.CPSubsystemException) LogEntry(com.hazelcast.cp.internal.raft.impl.log.LogEntry) RaftLog(com.hazelcast.cp.internal.raft.impl.log.RaftLog)

Example 3 with LogEntry

use of com.hazelcast.cp.internal.raft.impl.log.LogEntry in project hazelcast by hazelcast.

the class LeadershipTransferTask method run.

@Override
public void run() {
    ILogger logger = raftNode.getLogger(getClass());
    RaftState state = raftNode.state();
    LeaderState leaderState = state.leaderState();
    if (leaderState == null) {
        logger.fine("Not retrying leadership transfer since not leader...");
        return;
    }
    LeadershipTransferState leadershipTransferState = state.leadershipTransferState();
    checkTrue(leadershipTransferState != null, "No leadership transfer state!");
    if (retryCount == maxRetryCount) {
        String msg = "Leadership transfer to " + leadershipTransferState.endpoint() + " timed out!";
        logger.warning(msg);
        state.completeLeadershipTransfer(new IllegalStateException(msg));
        return;
    }
    RaftEndpoint targetEndpoint = leadershipTransferState.endpoint();
    if (state.commitIndex() < state.log().lastLogOrSnapshotIndex()) {
        logger.warning("Waiting until all appended entries to be committed before transferring leadership to " + targetEndpoint);
        reschedule();
        return;
    }
    if (retryCount > 0) {
        logger.fine("Retrying leadership transfer to " + leadershipTransferState.endpoint());
    } else {
        logger.info("Transferring leadership to " + leadershipTransferState.endpoint());
    }
    leaderState.getFollowerState(targetEndpoint).appendRequestAckReceived();
    raftNode.sendAppendRequest(targetEndpoint);
    LogEntry entry = state.log().lastLogOrSnapshotEntry();
    raftNode.send(new TriggerLeaderElection(raftNode.getLocalMember(), state.term(), entry.term(), entry.index()), targetEndpoint);
    reschedule();
}
Also used : RaftState(com.hazelcast.cp.internal.raft.impl.state.RaftState) RaftEndpoint(com.hazelcast.cp.internal.raft.impl.RaftEndpoint) ILogger(com.hazelcast.logging.ILogger) LeadershipTransferState(com.hazelcast.cp.internal.raft.impl.state.LeadershipTransferState) TriggerLeaderElection(com.hazelcast.cp.internal.raft.impl.dto.TriggerLeaderElection) LogEntry(com.hazelcast.cp.internal.raft.impl.log.LogEntry) LeaderState(com.hazelcast.cp.internal.raft.impl.state.LeaderState)

Example 4 with LogEntry

use of com.hazelcast.cp.internal.raft.impl.log.LogEntry in project hazelcast by hazelcast.

the class AppendRequest method writeData.

@Override
public void writeData(ObjectDataOutput out) throws IOException {
    out.writeInt(term);
    out.writeObject(leader);
    out.writeInt(prevLogTerm);
    out.writeLong(prevLogIndex);
    out.writeLong(leaderCommitIndex);
    out.writeInt(entries.length);
    for (LogEntry entry : entries) {
        out.writeObject(entry);
    }
    out.writeLong(queryRound);
}
Also used : LogEntry(com.hazelcast.cp.internal.raft.impl.log.LogEntry)

Example 5 with LogEntry

use of com.hazelcast.cp.internal.raft.impl.log.LogEntry in project hazelcast by hazelcast.

the class RaftNodeImpl method applyRestoredRaftGroupCommands.

private void applyRestoredRaftGroupCommands(SnapshotEntry snapshot) {
    // If there is a single Raft group command after the last snapshot,
    // here we cannot know if the that command is committed or not so we
    // just "pre-apply" that command without committing it.
    // If there are multiple Raft group commands, it is definitely known
    // that all the command up to the last command are committed,
    // but the last command may not be committed.
    // This conclusion boils down to the fact that once you append a Raft
    // group command, you cannot append a new one before committing it.
    RaftLog log = state.log();
    LogEntry committedEntry = null;
    LogEntry lastAppliedEntry = null;
    for (long i = snapshot != null ? snapshot.index() + 1 : 1; i <= log.lastLogOrSnapshotIndex(); i++) {
        LogEntry entry = log.getLogEntry(i);
        assert entry != null : "index: " + i;
        if (entry.operation() instanceof RaftGroupCmd) {
            committedEntry = lastAppliedEntry;
            lastAppliedEntry = entry;
        }
    }
    if (committedEntry != null) {
        state.commitIndex(committedEntry.index());
        applyLogEntries();
    }
    if (lastAppliedEntry != null) {
        if (lastAppliedEntry.operation() instanceof UpdateRaftGroupMembersCmd) {
            setStatus(UPDATING_GROUP_MEMBER_LIST);
            Collection<RaftEndpoint> members = ((UpdateRaftGroupMembersCmd) lastAppliedEntry.operation()).getMembers();
            updateGroupMembers(lastAppliedEntry.index(), members);
        } else if (lastAppliedEntry.operation() instanceof DestroyRaftGroupCmd) {
            setStatus(TERMINATING);
        } else {
            throw new IllegalStateException("Invalid group command for restore: " + lastAppliedEntry);
        }
    }
}
Also used : UpdateRaftGroupMembersCmd(com.hazelcast.cp.internal.raft.impl.command.UpdateRaftGroupMembersCmd) DestroyRaftGroupCmd(com.hazelcast.cp.internal.raft.command.DestroyRaftGroupCmd) RaftGroupCmd(com.hazelcast.cp.internal.raft.command.RaftGroupCmd) DestroyRaftGroupCmd(com.hazelcast.cp.internal.raft.command.DestroyRaftGroupCmd) LogEntry(com.hazelcast.cp.internal.raft.impl.log.LogEntry) RaftLog(com.hazelcast.cp.internal.raft.impl.log.RaftLog)

Aggregations

LogEntry (com.hazelcast.cp.internal.raft.impl.log.LogEntry)20 RaftLog (com.hazelcast.cp.internal.raft.impl.log.RaftLog)10 ParallelJVMTest (com.hazelcast.test.annotation.ParallelJVMTest)8 QuickTest (com.hazelcast.test.annotation.QuickTest)8 Test (org.junit.Test)8 ApplyRaftRunnable (com.hazelcast.cp.internal.raft.impl.dataservice.ApplyRaftRunnable)4 RaftState (com.hazelcast.cp.internal.raft.impl.state.RaftState)4 List (java.util.List)4 HazelcastInstance (com.hazelcast.core.HazelcastInstance)3 CPGroupId (com.hazelcast.cp.CPGroupId)3 ResourceRegistry (com.hazelcast.cp.internal.datastructures.spi.blocking.ResourceRegistry)3 RaftEndpoint (com.hazelcast.cp.internal.raft.impl.RaftEndpoint)3 RaftNodeImpl (com.hazelcast.cp.internal.raft.impl.RaftNodeImpl)3 UpdateRaftGroupMembersCmd (com.hazelcast.cp.internal.raft.impl.command.UpdateRaftGroupMembersCmd)3 RestoredRaftState (com.hazelcast.cp.internal.raft.impl.persistence.RestoredRaftState)3 LocalRaftGroupBuilder (com.hazelcast.cp.internal.raft.impl.testing.LocalRaftGroup.LocalRaftGroupBuilder)3 DestroyRaftGroupCmd (com.hazelcast.cp.internal.raft.command.DestroyRaftGroupCmd)2 RaftGroupCmd (com.hazelcast.cp.internal.raft.command.RaftGroupCmd)2 AppendRequest (com.hazelcast.cp.internal.raft.impl.dto.AppendRequest)2 AppendSuccessResponse (com.hazelcast.cp.internal.raft.impl.dto.AppendSuccessResponse)2