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;
}
use of io.aeron.cluster.client.ClusterEvent in project Aeron by real-logic.
the class ConsensusModuleAgent method replayLogPoll.
int replayLogPoll(final LogAdapter logAdapter, final long stopPosition) {
int workCount = 0;
if (ConsensusModule.State.ACTIVE == state || ConsensusModule.State.SUSPENDED == state) {
final int fragments = logAdapter.poll(stopPosition);
final long position = logAdapter.position();
if (fragments > 0) {
commitPosition.setOrdered(position);
} else if (logAdapter.isImageClosed() && position < stopPosition) {
throw new ClusterEvent("unexpected image close when replaying log: position=" + position);
}
workCount += fragments;
}
workCount += consensusModuleAdapter.poll();
return workCount;
}
use of io.aeron.cluster.client.ClusterEvent in project Aeron by real-logic.
the class ConsensusModuleAgent method pollArchiveEvents.
int pollArchiveEvents() {
int workCount = 0;
if (null != archive) {
final RecordingSignalPoller poller = this.recordingSignalPoller;
workCount += poller.poll();
if (poller.isPollComplete()) {
final int templateId = poller.templateId();
if (ControlResponseDecoder.TEMPLATE_ID == templateId && poller.code() == ControlResponseCode.ERROR) {
for (final ClusterMember member : activeMembers) {
if (member.catchupReplayCorrelationId() == poller.correlationId()) {
member.catchupReplaySessionId(NULL_VALUE);
member.catchupReplayCorrelationId(NULL_VALUE);
ctx.countedErrorHandler().onError(new ClusterEvent("catchup replay failed - " + poller.errorMessage()));
return workCount;
}
}
final ArchiveException ex = new ArchiveException(poller.errorMessage(), (int) poller.relevantId(), poller.correlationId());
if (ex.errorCode() == ArchiveException.STORAGE_SPACE) {
ctx.countedErrorHandler().onError(ex);
unexpectedTermination();
}
if (null != election) {
election.handleError(clusterClock.timeNanos(), ex);
}
} else if (RecordingSignalEventDecoder.TEMPLATE_ID == templateId) {
final long recordingId = poller.recordingId();
final long position = poller.recordingPosition();
final RecordingSignal signal = poller.recordingSignal();
if (RecordingSignal.STOP == signal && recordingId == logRecordingId) {
this.logRecordedPosition = position;
}
if (null != election) {
election.onRecordingSignal(poller.correlationId(), recordingId, position, signal);
}
if (null != dynamicJoin) {
dynamicJoin.onRecordingSignal(poller.correlationId(), recordingId, position, signal);
}
}
} else if (0 == workCount && !poller.subscription().isConnected()) {
ctx.countedErrorHandler().onError(new ClusterEvent("local archive is not connected"));
unexpectedTermination();
}
}
return workCount;
}
use of io.aeron.cluster.client.ClusterEvent in project Aeron by real-logic.
the class ConsensusModuleAgent method onCommitPosition.
void onCommitPosition(final long leadershipTermId, final long logPosition, final int leaderMemberId) {
if (null != election) {
election.onCommitPosition(leadershipTermId, logPosition, leaderMemberId);
} else if (leadershipTermId == this.leadershipTermId && leaderMemberId == leaderMember.id() && Cluster.Role.FOLLOWER == role) {
notifiedCommitPosition = logPosition;
timeOfLastLogUpdateNs = clusterClock.timeNanos();
} else if (leadershipTermId > this.leadershipTermId && null == dynamicJoin) {
ctx.countedErrorHandler().onError(new ClusterEvent("unexpected commit position from new leader"));
enterElection();
}
}
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;
}
Aggregations