Search in sources :

Example 1 with NotCurrentLeaderException

use of com.palantir.leader.NotCurrentLeaderException in project atlasdb by palantir.

the class AwaitingLeadershipProxy method handleInvocation.

@Override
protected Object handleInvocation(Object proxy, Method method, Object[] args) throws Throwable {
    final LeadershipToken leadershipToken = leadershipTokenRef.get();
    if (leadershipToken == null) {
        throw notCurrentLeaderException("method invoked on a non-leader");
    }
    if (method.getName().equals("close") && args.length == 0) {
        isClosed = true;
        executor.shutdownNow();
        clearDelegate();
        return null;
    }
    Object delegate = delegateRef.get();
    StillLeadingStatus leading = null;
    for (int i = 0; i < MAX_NO_QUORUM_RETRIES; i++) {
        // TODO(nziebart): check if leadershipTokenRef has been nulled out between iterations?
        leading = leaderElectionService.isStillLeading(leadershipToken);
        if (leading != StillLeadingStatus.NO_QUORUM) {
            break;
        }
    }
    // and should assume we're not the leader
    if (leading == StillLeadingStatus.NOT_LEADING || leading == StillLeadingStatus.NO_QUORUM) {
        markAsNotLeading(leadershipToken, null);
    }
    if (isClosed) {
        throw new IllegalStateException("already closed proxy for " + interfaceClass.getName());
    }
    Preconditions.checkNotNull(delegate, "%s backing is null", interfaceClass.getName());
    try {
        return method.invoke(delegate, args);
    } catch (InvocationTargetException e) {
        if (e.getTargetException() instanceof ServiceNotAvailableException || e.getTargetException() instanceof NotCurrentLeaderException) {
            markAsNotLeading(leadershipToken, e.getCause());
        }
        // Prevent blocked lock requests from receiving a non-retryable 500 on interrupts in case of a leader election.
        if (e.getTargetException() instanceof InterruptedException && !isStillCurrentToken(leadershipToken)) {
            throw notCurrentLeaderException("received an interrupt due to leader election.", e.getTargetException());
        }
        throw e.getTargetException();
    }
}
Also used : ServiceNotAvailableException(com.palantir.common.remoting.ServiceNotAvailableException) LeadershipToken(com.palantir.leader.LeaderElectionService.LeadershipToken) StillLeadingStatus(com.palantir.leader.LeaderElectionService.StillLeadingStatus) NotCurrentLeaderException(com.palantir.leader.NotCurrentLeaderException) InvocationTargetException(java.lang.reflect.InvocationTargetException)

Example 2 with NotCurrentLeaderException

use of com.palantir.leader.NotCurrentLeaderException in project atlasdb by palantir.

the class PaxosTimestampBoundStore method storeUpperLimit.

/**
 * Proposes a new timestamp limit, with sequence number 1 greater than the current agreed bound, or
 * PaxosAcceptor.NO_LOG_ENTRY + 1 if nothing has been proposed or accepted yet.
 *
 * @param limit the new upper limit to be stored
 * @throws IllegalArgumentException if trying to persist a limit smaller than the agreed limit
 * @throws NotCurrentLeaderException if the timestamp limit has changed out from under us
 */
@Override
public synchronized void storeUpperLimit(long limit) throws MultipleRunningTimestampServiceError {
    long newSeq = PaxosAcceptor.NO_LOG_ENTRY + 1;
    if (agreedState != null) {
        Preconditions.checkArgument(limit >= agreedState.getBound(), "Tried to store an upper limit %s less than the current limit %s", limit, agreedState.getBound());
        newSeq = agreedState.getSeqId() + 1;
    }
    while (true) {
        try {
            proposer.propose(newSeq, PtBytes.toBytes(limit));
            PaxosValue value = knowledge.getLearnedValue(newSeq);
            checkAgreedBoundIsOurs(limit, newSeq, value);
            long newLimit = PtBytes.toLong(value.getData());
            agreedState = ImmutableSequenceAndBound.of(newSeq, newLimit);
            if (newLimit < limit) {
                // The bound is ours, but is not high enough.
                // This is dangerous; proposing at the next sequence number is unsafe, as timestamp services
                // generally assume they have the ALLOCATION_BUFFER_SIZE timestamps up to this.
                // TODO (jkong): Devise a method that better preserves availability of the cluster.
                log.warn("It appears we updated the timestamp limit to {}, which was less than our target {}." + " This suggests we have another timestamp service running; possibly because we" + " lost and regained leadership. For safety, we are now stopping this service.", SafeArg.of("newLimit", newLimit), SafeArg.of("target", limit));
                throw new NotCurrentLeaderException(String.format("We updated the timestamp limit to %s, which was less than our target %s.", newLimit, limit));
            }
            return;
        } catch (PaxosRoundFailureException e) {
            waitForRandomBackoff(e, this::wait);
        }
    }
}
Also used : PaxosRoundFailureException(com.palantir.paxos.PaxosRoundFailureException) NotCurrentLeaderException(com.palantir.leader.NotCurrentLeaderException) PaxosValue(com.palantir.paxos.PaxosValue)

Example 3 with NotCurrentLeaderException

use of com.palantir.leader.NotCurrentLeaderException in project atlasdb by palantir.

the class HeldLocksCollection method failAllOutstandingRequestsWithNotCurrentLeaderException.

public void failAllOutstandingRequestsWithNotCurrentLeaderException() {
    NotCurrentLeaderException ex = new NotCurrentLeaderException("This lock service has been closed");
    heldLocksById.values().forEach(result -> result.failIfNotCompleted(ex));
}
Also used : NotCurrentLeaderException(com.palantir.leader.NotCurrentLeaderException)

Aggregations

NotCurrentLeaderException (com.palantir.leader.NotCurrentLeaderException)3 ServiceNotAvailableException (com.palantir.common.remoting.ServiceNotAvailableException)1 LeadershipToken (com.palantir.leader.LeaderElectionService.LeadershipToken)1 StillLeadingStatus (com.palantir.leader.LeaderElectionService.StillLeadingStatus)1 PaxosRoundFailureException (com.palantir.paxos.PaxosRoundFailureException)1 PaxosValue (com.palantir.paxos.PaxosValue)1 InvocationTargetException (java.lang.reflect.InvocationTargetException)1