Search in sources :

Example 1 with RaftGroupCmd

use of com.hazelcast.cp.internal.raft.command.RaftGroupCmd 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)

Example 2 with RaftGroupCmd

use of com.hazelcast.cp.internal.raft.command.RaftGroupCmd in project hazelcast by hazelcast.

the class RaftNodeImpl method canReplicateNewEntry.

/**
 * Returns true if a new entry with the operation is currently allowed to
 * be replicated. This method can be invoked only when the local Raft node
 * is the leader.
 * <p>
 * Replication is not allowed, when;
 * <ul>
 * <li>Node is terminating, terminated or stepped down. See {@link RaftNodeStatus}.</li>
 * <li>Raft log contains max allowed uncommitted entry count.
 * See {@link RaftAlgorithmConfig#getUncommittedEntryCountToRejectNewAppends()}.</li>
 * <li>The operation is a {@link RaftGroupCmd} and there's an ongoing membership change in group.</li>
 * <li>The operation is a membership change operation and there's no committed entry in this term yet.
 * See {@link RaftIntegration#getAppendedEntryOnLeaderElection()}.</li>
 * <li>There is an ongoing leadership transfer.</li>
 * </ul>
 */
public boolean canReplicateNewEntry(Object operation) {
    if (isTerminatedOrSteppedDown()) {
        return false;
    }
    RaftLog log = state.log();
    long lastLogIndex = log.lastLogOrSnapshotIndex();
    long commitIndex = state.commitIndex();
    if (lastLogIndex - commitIndex >= maxUncommittedEntryCount) {
        return false;
    }
    if (status == TERMINATING) {
        return false;
    } else if (status == UPDATING_GROUP_MEMBER_LIST) {
        return state.lastGroupMembers().isKnownMember(getLocalMember()) && !(operation instanceof RaftGroupCmd);
    }
    if (operation instanceof UpdateRaftGroupMembersCmd) {
        // the leader must have committed an entry in its term to make a membership change
        // https://groups.google.com/forum/#!msg/raft-dev/t4xj6dJTP6E/d2D9LrWRza8J
        // last committed entry is either in the last snapshot or still in the log
        LogEntry lastCommittedEntry = commitIndex == log.snapshotIndex() ? log.snapshot() : log.getLogEntry(commitIndex);
        assert lastCommittedEntry != null;
        return lastCommittedEntry.term() == state.term();
    }
    return state.leadershipTransferState() == null;
}
Also used : UpdateRaftGroupMembersCmd(com.hazelcast.cp.internal.raft.impl.command.UpdateRaftGroupMembersCmd) 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

DestroyRaftGroupCmd (com.hazelcast.cp.internal.raft.command.DestroyRaftGroupCmd)2 RaftGroupCmd (com.hazelcast.cp.internal.raft.command.RaftGroupCmd)2 UpdateRaftGroupMembersCmd (com.hazelcast.cp.internal.raft.impl.command.UpdateRaftGroupMembersCmd)2 LogEntry (com.hazelcast.cp.internal.raft.impl.log.LogEntry)2 RaftLog (com.hazelcast.cp.internal.raft.impl.log.RaftLog)2