@Override public LeadershipToken blockOnBecomingLeader() throws InterruptedException { while (true) { LeadershipState currentState = determineLeadershipState(); switch (currentState.status()) { case LEADING: log.info("Successfully became leader!"); return currentState.confirmedToken().get(); case NO_QUORUM: // If we don't have quorum we should just retry our calls. continue; case NOT_LEADING: proposeLeadershipOrWaitForBackoff(currentState); continue; default: throw new IllegalStateException("unknown status: " + currentState.status()); } } }
private void proposeLeadershipOrWaitForBackoff(LeadershipState currentState) throws InterruptedException { if (pingLeader()) { Thread.sleep(updatePollingRateInMs); return; } boolean learnedNewState = updateLearnedStateFromPeers(currentState.greatestLearnedValue()); if (learnedNewState) { return; } long backoffTime = (long) (randomWaitBeforeProposingLeadership * Math.random()); log.debug("Waiting for [{}] ms before proposing leadership", SafeArg.of("waitTimeMs", backoffTime)); Thread.sleep(backoffTime); proposeLeadershipAfter(currentState.greatestLearnedValue()); }
@Override public LeadershipToken blockOnBecomingLeader() throws InterruptedException { while (true) { LeadershipState currentState = determineLeadershipState(); switch (currentState.status()) { case LEADING: log.info("Successfully became leader!"); return currentState.confirmedToken().get(); case NO_QUORUM: // If we don't have quorum we should just retry our calls. continue; case NOT_LEADING: proposeLeadershipOrWaitForBackoff(currentState); continue; default: throw new IllegalStateException("unknown status: " + currentState.status()); } } }
private void proposeLeadershipOrWaitForBackoff(LeadershipState currentState) throws InterruptedException { if (pingLeader()) { Thread.sleep(updatePollingRateInMs); return; } boolean learnedNewState = updateLearnedStateFromPeers(currentState.greatestLearnedValue()); if (learnedNewState) { return; } long backoffTime = (long) (randomWaitBeforeProposingLeadership * Math.random()); log.debug("Waiting for [{}] ms before proposing leadership", SafeArg.of("waitTimeMs", backoffTime)); Thread.sleep(backoffTime); proposeLeadershipAfter(currentState.greatestLearnedValue()); }
@Override public Optional<LeadershipToken> getCurrentTokenIfLeading() { return determineLeadershipState().confirmedToken(); }
private LeadershipState determineLeadershipState() { Optional<PaxosValue> greatestLearnedValue = getGreatestLearnedPaxosValue(); StillLeadingStatus leadingStatus = determineLeadershipStatus(greatestLearnedValue); return LeadershipState.of(greatestLearnedValue, leadingStatus); }
default Optional<LeadershipToken> confirmedToken() { if (status() == StillLeadingStatus.LEADING) { return Optional.of(new PaxosLeadershipToken(greatestLearnedValue().get())); } return Optional.empty(); }
@Override public Optional<LeadershipToken> getCurrentTokenIfLeading() { return determineLeadershipState().confirmedToken(); }
private LeadershipState determineLeadershipState() { Optional<PaxosValue> greatestLearnedValue = getGreatestLearnedPaxosValue(); StillLeadingStatus leadingStatus = determineLeadershipStatus(greatestLearnedValue); return LeadershipState.of(greatestLearnedValue, leadingStatus); }
default Optional<LeadershipToken> confirmedToken() { if (status() == StillLeadingStatus.LEADING) { return Optional.of(new PaxosLeadershipToken(greatestLearnedValue().get())); } return Optional.empty(); }