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();
}
}
Aggregations