Search in sources :

Example 1 with StillLeadingStatus

use of com.palantir.leader.LeaderElectionService.StillLeadingStatus 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)

Aggregations

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