private LeadershipState determineLeadershipState() { Optional<PaxosValue> greatestLearnedValue = getGreatestLearnedPaxosValue(); StillLeadingStatus leadingStatus = determineLeadershipStatus(greatestLearnedValue); return LeadershipState.of(greatestLearnedValue, leadingStatus); }
@Override public synchronized void recordNoQuorum(PaxosValue value) { if (isSameRound(value)) { events.noQuorum(value); } }
@Override public Optional<LeadershipToken> getCurrentTokenIfLeading() { return determineLeadershipState().confirmedToken(); }
private synchronized void recordNewRound(PaxosValue round) { if (isLeading) { events.lostLeadershipFor(currentRound); leadershipObserver.ifPresent(LeadershipObserver::lostLeadership); } if (isLeaderFor(round)) { events.gainedLeadershipFor(round); leadershipObserver.ifPresent(LeadershipObserver::gainedLeadership); } currentRound = round; isLeading = isLeaderFor(round); }
@Test public void notifiesObserverIfLostLeadership() { recorder.recordRound(ROUND_1_LEADING); recorder.recordRound(ROUND_2_NOT_LEADING); verify(events).gainedLeadershipFor(ROUND_1_LEADING); verify(events).lostLeadershipFor(ROUND_1_LEADING); verify(observer).gainedLeadership(); verify(observer).lostLeadership(); }
default Optional<LeadershipToken> confirmedToken() { if (status() == StillLeadingStatus.LEADING) { return Optional.of(new PaxosLeadershipToken(greatestLearnedValue().get())); } return Optional.empty(); }
@Override public synchronized void recordNotLeading(PaxosValue value) { if (isSameRound(value) && isLeading) { events.lostLeadershipFor(value); leadershipObserver.ifPresent(LeadershipObserver::lostLeadership); isLeading = false; } }
@Test public void notifiesObserverIfGainedLeadership() { recorder.recordRound(ROUND_1_LEADING); verify(events).gainedLeadershipFor(ROUND_1_LEADING); verify(observer).gainedLeadership(); }
private void recordLeadershipStatus( PaxosLeadershipToken token, StillLeadingStatus status) { if (status == StillLeadingStatus.NO_QUORUM) { eventRecorder.recordNoQuorum(token.value); } else if (status == StillLeadingStatus.NOT_LEADING) { eventRecorder.recordNotLeading(token.value); } }
private StillLeadingStatus determineAndRecordLeadershipStatus( PaxosLeadershipToken paxosToken) { StillLeadingStatus status = determineLeadershipStatus(paxosToken.value); recordLeadershipStatus(paxosToken, status); return status; }
@Override public synchronized void recordRound(PaxosValue round) { if (isNewRound(round)) { recordNewRound(round); } }
public static PaxosLeadershipEventRecorder create(MetricRegistry metrics, String leaderUuid, LeadershipObserver observer) { return new PaxosLeadershipEventRecorder( new LeadershipEvents(metrics), leaderUuid, Optional.ofNullable(observer)); }
private void registerFollowerAndLeaderTasks() { leadershipObserver.executeWhenGainedLeadership(leaderTask); leadershipObserver.executeWhenLostLeadership(followerTask); }
@Override public void recordLeaderPingFailure(Throwable error) { events.leaderPingFailure(error); }
@Override public void recordLeaderPingReturnedFalse() { events.leaderPingReturnedFalse(); }
@Override public void recordProposalFailure(PaxosRoundFailureException paxosException) { events.proposalFailure(paxosException); }
@Override public Set<PingableLeader> getPotentialLeaders() { return delegate.getPotentialLeaders(); }
private PingResult pingRecordingException(PingableLeader leader) { try { return leader.ping() ? PingResult.SUCCESS : PingResult.FAILURE; } catch (Exception ex) { return PingResult.EXCEPTION; } } }
@Override public StillLeadingStatus isStillLeading(LeadershipToken token) { if (!(token instanceof PaxosLeadershipToken)) { return StillLeadingStatus.NOT_LEADING; } PaxosLeadershipToken paxosToken = (PaxosLeadershipToken) token; return determineAndRecordLeadershipStatus(paxosToken); }
public boolean isCurrentSuspectedLeader() { return localPingableLeader.ping(); } }