use of io.aeron.cluster.client.ClusterEvent in project aeron by real-logic.
the class ConsensusModuleAgent method slowTickWork.
private int slowTickWork(final long nowNs) {
int workCount = aeronClientInvoker.invoke();
if (aeron.isClosed()) {
throw new AgentTerminationException("unexpected Aeron close");
} else if (ConsensusModule.State.CLOSED == state) {
unexpectedTermination();
} else if (isElectionRequired) {
if (null == election) {
enterElection();
}
isElectionRequired = false;
}
if (nowNs >= markFileUpdateDeadlineNs) {
markFileUpdateDeadlineNs = nowNs + MARK_FILE_UPDATE_INTERVAL_NS;
markFile.updateActivityTimestamp(clusterClock.timeMillis());
}
workCount += pollArchiveEvents();
workCount += sendRedirects(redirectSessions, nowNs);
workCount += sendRejections(rejectedSessions, nowNs);
if (null == election) {
if (Cluster.Role.LEADER == role) {
workCount += checkControlToggle(nowNs);
if (ConsensusModule.State.ACTIVE == state) {
workCount += processPendingSessions(pendingSessions, nowNs);
workCount += checkSessions(sessionByIdMap, nowNs);
workCount += processPassiveMembers(passiveMembers);
if (!ClusterMember.hasActiveQuorum(activeMembers, nowNs, leaderHeartbeatTimeoutNs)) {
ctx.countedErrorHandler().onError(new ClusterEvent("inactive follower quorum"));
enterElection();
workCount += 1;
}
} else if (ConsensusModule.State.TERMINATING == state) {
if (clusterTermination.canTerminate(activeMembers, terminationPosition, nowNs)) {
recordingLog.commitLogPosition(leadershipTermId, terminationPosition);
closeAndTerminate();
}
}
} else if (ConsensusModule.State.ACTIVE == state || ConsensusModule.State.SUSPENDED == state) {
if (nowNs >= (timeOfLastLogUpdateNs + leaderHeartbeatTimeoutNs) && NULL_POSITION == terminationPosition) {
ctx.countedErrorHandler().onError(new ClusterEvent("leader heartbeat timeout"));
enterElection();
workCount += 1;
}
}
}
return workCount;
}
use of io.aeron.cluster.client.ClusterEvent in project Aeron by real-logic.
the class ConsensusModuleAgent method onNewLeadershipTerm.
void onNewLeadershipTerm(final long logLeadershipTermId, final long nextLeadershipTermId, final long nextTermBaseLogPosition, final long nextLogPosition, final long leadershipTermId, final long termBaseLogPosition, final long logPosition, final long leaderRecordingId, final long timestamp, final int leaderId, final int logSessionId, final boolean isStartup) {
if (null != election) {
election.onNewLeadershipTerm(logLeadershipTermId, nextLeadershipTermId, nextTermBaseLogPosition, nextLogPosition, leadershipTermId, termBaseLogPosition, logPosition, leaderRecordingId, timestamp, leaderId, logSessionId, isStartup);
} else if (Cluster.Role.FOLLOWER == role && leadershipTermId == this.leadershipTermId && leaderId == leaderMember.id()) {
notifiedCommitPosition = Math.max(notifiedCommitPosition, logPosition);
timeOfLastLogUpdateNs = clusterClock.timeNanos();
} else if (leadershipTermId > this.leadershipTermId && null == dynamicJoin) {
ctx.countedErrorHandler().onError(new ClusterEvent("unexpected new leadership term event"));
enterElection();
}
}
use of io.aeron.cluster.client.ClusterEvent in project aeron by real-logic.
the class ConsensusModuleAgent method onUnavailableCounter.
private void onUnavailableCounter(final CountersReader counters, final long registrationId, final int counterId) {
if (ConsensusModule.State.TERMINATING != state && ConsensusModule.State.QUITTING != state) {
for (final long clientId : serviceClientIds) {
if (registrationId == clientId) {
ctx.countedErrorHandler().onError(new ClusterEvent("Aeron client in service closed unexpectedly"));
state(ConsensusModule.State.CLOSED);
return;
}
}
if (null != appendPosition && appendPosition.registrationId() == registrationId) {
appendPosition = null;
logSubscriptionId = NULL_VALUE;
if (null != election) {
election.handleError(clusterClock.timeNanos(), new ClusterEvent("log recording ended unexpectedly (null != election)"));
} else if (NULL_POSITION == terminationPosition) {
ctx.countedErrorHandler().onError(new ClusterEvent("log recording ended unexpectedly (NULL_POSITION == terminationPosition"));
isElectionRequired = true;
}
}
}
}
use of io.aeron.cluster.client.ClusterEvent in project aeron by real-logic.
the class ConsensusModuleAgent method consensusWork.
private int consensusWork(final long timestamp, final long nowNs) {
int workCount = 0;
if (Cluster.Role.LEADER == role) {
if (ConsensusModule.State.ACTIVE == state) {
workCount += timerService.poll(timestamp);
workCount += pendingServiceMessages.forEach(pendingServiceMessageHeadOffset, serviceSessionMessageAppender, SERVICE_MESSAGE_LIMIT);
workCount += ingressAdapter.poll();
}
workCount += updateLeaderPosition(nowNs);
} else {
if (ConsensusModule.State.ACTIVE == state || ConsensusModule.State.SUSPENDED == state) {
if (NULL_POSITION != terminationPosition && logAdapter.position() >= terminationPosition) {
serviceProxy.terminationPosition(terminationPosition, ctx.countedErrorHandler());
state(ConsensusModule.State.TERMINATING);
} else {
final long limit = null != appendPosition ? appendPosition.get() : logRecordedPosition;
final int count = logAdapter.poll(min(notifiedCommitPosition, limit));
if (0 == count && logAdapter.isImageClosed()) {
ctx.countedErrorHandler().onError(new ClusterEvent("log disconnected from leader"));
enterElection();
return 1;
}
commitPosition.proposeMaxOrdered(logAdapter.position());
workCount += ingressAdapter.poll();
workCount += count;
}
}
workCount += updateFollowerPosition(nowNs);
}
workCount += consensusModuleAdapter.poll();
return workCount;
}
Aggregations