private BlockingTimeLimitedLockService createService(TimeLimiter limiter) { return new BlockingTimeLimitedLockService(delegate, limiter, BLOCKING_TIME_LIMIT_MILLIS); } }
@Nullable @Override public LockRefreshToken lock(@PathParam("client") String client, LockRequest request) throws InterruptedException { return callWithTimeLimit( () -> delegate.lock(client, request), ImmutableLockRequestSpecification.of("lock", client, request)); }
private void verifyCurrentTimeMillisDelegates(BlockingTimeLimitedLockService service) { when(delegate.currentTimeMillis()).thenReturn(TEST_CURRENT_TIME_MILLIS); assertThat(service.currentTimeMillis()).isEqualTo(TEST_CURRENT_TIME_MILLIS); verify(delegate, times(1)).currentTimeMillis(); }
private <T> T callWithTimeLimit(Callable<T> callable, LockRequestSpecification specification) throws InterruptedException { try { return timeLimiter.callWithTimeout(callable, blockingTimeLimitMillis, TimeUnit.MILLISECONDS); } catch (InterruptedException e) { // In this case, the thread was interrupted for some other reason, perhaps because we lost leadership. log.info("Lock service was interrupted when servicing {} for client \"{}\"; request was {}", SafeArg.of("method", specification.method()), SafeArg.of("client", specification.client()), UnsafeArg.of("lockRequest", specification.lockRequest()), e); throw e; } catch (TimeoutException e) { // This is the legitimate timeout case we're trying to catch. throw logAndHandleTimeout(specification); } catch (Exception e) { // We don't know, and would prefer not to throw checked exceptions apart from InterruptedException. throw Throwables.propagate(e); } }
@Test public void throwsBlockingTimeoutExceptionIfInterruptibleOperationTimesOut() { assertThatThrownBy(() -> timingOutService.lock(CLIENT, LOCK_REQUEST)) .isInstanceOf(BlockingTimeoutException.class); }
@Test public void rethrowsInterruptedExceptionIfInterruptibleOperationIsInterrupted() { assertThatThrownBy(() -> interruptingService.lockAndGetHeldLocks(CLIENT, LOCK_REQUEST)) .isInstanceOf(InterruptedException.class); }
@Test public void closesDelegate() throws IOException { acceptingService.close(); verify(delegate).close(); }
private CloseableLockService createTimeLimitedLockService(long slowLogTriggerMillis) { LockServerOptions lockServerOptions = LockServerOptions.builder() .slowLogTriggerMillis(slowLogTriggerMillis) .build(); LockServiceImpl rawLockService = LockServiceImpl.create(lockServerOptions); if (deprecated.useLockTimeLimiter()) { return BlockingTimeLimitedLockService.create( rawLockService, deprecated.blockingTimeoutInMs()); } return rawLockService; } }
private <T> T callWithTimeLimit(Callable<T> callable, LockRequestSpecification specification) throws InterruptedException { try { return timeLimiter.callWithTimeout(callable, blockingTimeLimitMillis, TimeUnit.MILLISECONDS); } catch (InterruptedException e) { // In this case, the thread was interrupted for some other reason, perhaps because we lost leadership. log.info("Lock service was interrupted when servicing {} for client \"{}\"; request was {}", SafeArg.of("method", specification.method()), SafeArg.of("client", specification.client()), UnsafeArg.of("lockRequest", specification.lockRequest()), e); throw e; } catch (TimeoutException e) { // This is the legitimate timeout case we're trying to catch. throw logAndHandleTimeout(specification); } catch (Exception e) { // We don't know, and would prefer not to throw checked exceptions apart from InterruptedException. throw Throwables.propagate(e); } }
@Test public void delegatesInterruptibleOperations() throws InterruptedException { acceptingService.lock(CLIENT, LOCK_REQUEST); verify(delegate, times(1)).lock(CLIENT, LOCK_REQUEST); }
public static BlockingTimeLimitedLockService create(CloseableLockService lockService, long blockingTimeLimitMillis) { // TODO (jkong): Inject the executor to allow application lifecycle managed executors. // Currently maintaining existing behaviour. return new BlockingTimeLimitedLockService( lockService, SimpleTimeLimiter.create(PTExecutors.newCachedThreadPool()), blockingTimeLimitMillis); }
@Override public HeldLocksToken lockAndGetHeldLocks(@PathParam("client") String client, LockRequest request) throws InterruptedException { return callWithTimeLimit( () -> delegate.lockAndGetHeldLocks(client, request), ImmutableLockRequestSpecification.of("lockAndGetHeldLocks", client, request)); }
@Test public void rethrowsExceptionOccurringFromInterruptibleOperation() { assertThatThrownBy(() -> throwingService.lock(LockClient.ANONYMOUS.getClientId(), LOCK_REQUEST)) .isInstanceOf(IllegalStateException.class); }
public static BlockingTimeLimitedLockService create(CloseableLockService lockService, long blockingTimeLimitMillis) { // TODO (jkong): Inject the executor to allow application lifecycle managed executors. // Currently maintaining existing behaviour. return new BlockingTimeLimitedLockService( lockService, SimpleTimeLimiter.create(PTExecutors.newCachedThreadPool()), blockingTimeLimitMillis); }
@Override public LockResponse lockWithFullLockResponse(LockClient client, LockRequest request) throws InterruptedException { return callWithTimeLimit( () -> delegate.lockWithFullLockResponse(client, request), ImmutableLockRequestSpecification.of("lockWithFullLockResponse", client.getClientId(), request)); }
@Nullable @Override public LockRefreshToken lock(@PathParam("client") String client, LockRequest request) throws InterruptedException { return callWithTimeLimit( () -> delegate.lock(client, request), ImmutableLockRequestSpecification.of("lock", client, request)); }
@Override public HeldLocksToken lockAndGetHeldLocks(@PathParam("client") String client, LockRequest request) throws InterruptedException { return callWithTimeLimit( () -> delegate.lockAndGetHeldLocks(client, request), ImmutableLockRequestSpecification.of("lockAndGetHeldLocks", client, request)); }
@Override public LockResponse lockWithFullLockResponse(LockClient client, LockRequest request) throws InterruptedException { return callWithTimeLimit( () -> delegate.lockWithFullLockResponse(client, request), ImmutableLockRequestSpecification.of("lockWithFullLockResponse", client.getClientId(), request)); }