private boolean gainLeadershipBlocking() { log.debug("Block until gained leadership"); try { LeadershipToken leadershipToken = leaderElectionService.blockOnBecomingLeader(); onGainedLeadership(leadershipToken); return true; } catch (InterruptedException e) { log.warn("attempt to gain leadership interrupted", e); } catch (Throwable e) { log.error("problem blocking on leadership", e); } return false; }
@Override public LeadershipToken blockOnBecomingLeader() throws InterruptedException { try { return leaseTokens.get(delegate.blockOnBecomingLeader()); } catch (CompletionException e) { if (e.getCause() instanceof InterruptedException) { throw new InterruptedException(); } throw e; } }
private void loseLeadership(Callable proxy) throws InterruptedException { when(leaderElectionService.isStillLeading(any())) .thenReturn(LeaderElectionService.StillLeadingStatus.NOT_LEADING); when(leaderElectionService.blockOnBecomingLeader()).then(invocation -> { // never return LockSupport.park(); return null; }); // make a call so the proxy will realize that it has lost leadership assertThatThrownBy(proxy::call).isInstanceOf(NotCurrentLeaderException.class) .hasMessage("method invoked on a non-leader (leadership lost)"); }
@Test public void shouldRetryBecomingLeader() throws Exception { when(leaderElectionService.blockOnBecomingLeader()) .thenThrow(new RuntimeException()) .thenReturn(leadershipToken); Runnable proxy = AwaitingLeadershipProxy.newProxyInstance( Runnable.class, delegateSupplier, leaderElectionService); Thread.sleep(1000); //wait for retrying on gaining leadership proxy.run(); verify(leaderElectionService, atLeast(2)).blockOnBecomingLeader(); }
@Test public void testThrowsInterruptedExceptionIfDelegateThrowsInterruptedException() throws InterruptedException { when(delegate.blockOnBecomingLeader()).thenThrow(new InterruptedException()); assertThatExceptionOfType(InterruptedException.class).isThrownBy(() -> leased.blockOnBecomingLeader()); }
@Test public void testDelaysAcquiringLeadership() throws Exception { long before = System.nanoTime(); leased.blockOnBecomingLeader(); long after = System.nanoTime(); assertThat(after - before).isGreaterThan(TIMEOUT.toNanos()); }
@Test public void shouldGainLeadershipImmediatelyIfAlreadyLeading() throws Exception { when(leaderElectionService.getCurrentTokenIfLeading()).thenReturn(Optional.of(leadershipToken)); Callable proxy = proxyFor(() -> null); proxy.call(); verify(leaderElectionService, never()).blockOnBecomingLeader(); }
@Before public void before() throws InterruptedException { when(leaderElectionService.blockOnBecomingLeader()).thenReturn(leadershipToken); when(leaderElectionService.getCurrentTokenIfLeading()).thenReturn(Optional.empty()); when(leaderElectionService.getSuspectedLeaderInMemory()).thenReturn(Optional.empty()); when(leaderElectionService.isStillLeading(leadershipToken)).thenReturn( LeaderElectionService.StillLeadingStatus.LEADING); }
@Test public void testIsNotLeadingIfWaiting() { Thread thread = new Thread(() -> { try { leased.blockOnBecomingLeader(); } catch (InterruptedException e) { throw new RuntimeException(e); } }); thread.start(); while (thread.getState() != Thread.State.TIMED_WAITING) { Thread.yield(); } assertThat(leased.getCurrentTokenIfLeading()).isEmpty(); }
@Test public void leasesLeadershipState() throws InterruptedException { LeadershipToken leasedToken = leased.blockOnBecomingLeader(); when(delegate.isStillLeading(token)).thenReturn(StillLeadingStatus.LEADING); assertThat(leased.isStillLeading(leasedToken)).isEqualTo(StillLeadingStatus.LEADING); assertThat(leased.isStillLeading(leasedToken)).isEqualTo(StillLeadingStatus.LEADING); verify(delegate).isStillLeading(token); }
@Before public void before() throws InterruptedException { // cache forever leased = new LeasingLeaderElectionService(() -> true, delegate, Duration.ofDays(1), TIMEOUT); when(delegate.blockOnBecomingLeader()).thenReturn(token); when(delegate.getCurrentTokenIfLeading()).thenReturn(Optional.of(token)); }
@Test public void shouldBlockOnGainingLeadershipIfNotCurrentlyLeading() throws Exception { Callable proxy = proxyFor(() -> null); waitForLeadershipToBeGained(); proxy.call(); verify(leaderElectionService).getCurrentTokenIfLeading(); verify(leaderElectionService).blockOnBecomingLeader(); }
public LeadershipToken gainLeadership(int leaderNum, boolean checkAfterwards) { LeaderElectionService.LeadershipToken token = null; try { token = leader(leaderNum).blockOnBecomingLeader(); } catch (InterruptedException e) { fail(e.getMessage()); } if (checkAfterwards) { assertEquals( "leader should still be leading right after becoming leader", StillLeadingStatus.LEADING, leader(leaderNum).isStillLeading(token)); } return token; }
private boolean gainLeadershipBlocking() { log.debug("Block until gained leadership"); try { LeadershipToken leadershipToken = leaderElectionService.blockOnBecomingLeader(); onGainedLeadership(leadershipToken); return true; } catch (InterruptedException e) { log.warn("attempt to gain leadership interrupted", e); } catch (Throwable e) { log.error("problem blocking on leadership", e); } return false; }
@Override public LeadershipToken blockOnBecomingLeader() throws InterruptedException { try { return leaseTokens.get(delegate.blockOnBecomingLeader()); } catch (CompletionException e) { if (e.getCause() instanceof InterruptedException) { throw new InterruptedException(); } throw e; } }