use of com.palantir.leader.LeaderElectionService.LeadershipToken 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();
}
}
use of com.palantir.leader.LeaderElectionService.LeadershipToken in project atlasdb by palantir.
the class AwaitingLeadershipProxy method gainLeadershipBlocking.
private void gainLeadershipBlocking() {
try {
LeadershipToken leadershipToken = leaderElectionService.blockOnBecomingLeader();
onGainedLeadership(leadershipToken);
} catch (InterruptedException e) {
log.warn("attempt to gain leadership interrupted", e);
} catch (Throwable e) {
log.error("problem blocking on leadership", e);
}
}
use of com.palantir.leader.LeaderElectionService.LeadershipToken in project atlasdb by palantir.
the class PaxosConsensusFastTest method loseQuorum.
@Test
public void loseQuorum() {
LeadershipToken t = state.gainLeadership(0);
for (int i = 1; i < NUM_POTENTIAL_LEADERS - QUORUM_SIZE + 2; i++) {
state.goDown(i);
}
assertFalse("leader cannot maintain leadership withou quorum", state.leader(0).isStillLeading(t) == StillLeadingStatus.LEADING);
state.comeUp(1);
state.gainLeadership(0);
assertTrue("leader can confirm leadership with quorum", state.leader(0).isStillLeading(t) != StillLeadingStatus.NOT_LEADING);
}
use of com.palantir.leader.LeaderElectionService.LeadershipToken in project atlasdb by palantir.
the class PaxosConsensusFastTest method loseQuorumDiffToken.
@Test
public void loseQuorumDiffToken() throws InterruptedException {
for (int i = QUORUM_SIZE; i < NUM_POTENTIAL_LEADERS; i++) {
state.goDown(i);
}
LeadershipToken t = state.gainLeadership(0);
state.goDown(QUORUM_SIZE - 1);
ExecutorService exec = PTExecutors.newSingleThreadExecutor();
Future<Void> f = exec.submit(() -> {
int i = QUORUM_SIZE - 1;
while (!Thread.currentThread().isInterrupted()) {
int next = i + 1;
if (next == NUM_POTENTIAL_LEADERS) {
next = QUORUM_SIZE - 1;
}
state.goDown(next);
state.comeUp(i);
i = next;
}
return null;
});
// Don't check leadership immediately after gaining it, since quorum might get lost.
LeadershipToken token2 = state.gainLeadershipWithoutCheckingAfter(0);
assertTrue("leader can confirm leadership with quorum", t.sameAs(token2));
f.cancel(true);
exec.shutdown();
exec.awaitTermination(10, TimeUnit.SECONDS);
for (int i = 0; i < NUM_POTENTIAL_LEADERS; i++) {
state.comeUp(i);
}
}
Aggregations