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);
}
}
}
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;
}
Aggregations