Search in sources :

Example 1 with ClusterEvent

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;
}
Also used : ClusterEvent(io.aeron.cluster.client.ClusterEvent)

Example 2 with ClusterEvent

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;
}
Also used : ClusterEvent(io.aeron.cluster.client.ClusterEvent)

Example 3 with ClusterEvent

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;
}
Also used : ClusterEvent(io.aeron.cluster.client.ClusterEvent) RecordingSignalPoller(io.aeron.archive.client.RecordingSignalPoller) ArchiveException(io.aeron.archive.client.ArchiveException)

Example 4 with ClusterEvent

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();
    }
}
Also used : ClusterEvent(io.aeron.cluster.client.ClusterEvent)

Example 5 with ClusterEvent

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;
}
Also used : ClusterEvent(io.aeron.cluster.client.ClusterEvent)

Aggregations

ClusterEvent (io.aeron.cluster.client.ClusterEvent)14 ArchiveException (io.aeron.archive.client.ArchiveException)2 RecordingSignalPoller (io.aeron.archive.client.RecordingSignalPoller)2