public AsyncResult<LockToken> lockImmutableTimestamp(UUID requestId, long timestamp) { return heldLocks.getExistingOrAcquire( requestId, () -> acquireImmutableTimestampLock(requestId, timestamp)); }
public Set<LockToken> refresh(Set<LockToken> tokens) { return heldLocks.refresh(tokens); }
private void scheduleExpiredLockReaper() { reaperExecutor.scheduleAtFixedRate(() -> { try { heldLocks.removeExpired(); } catch (Throwable t) { log.warn("Error while removing expired lock requests. Trying again on next iteration.", t); } }, 0, LeaseExpirationTimer.LEASE_TIMEOUT_MILLIS / 2, TimeUnit.MILLISECONDS); }
public Set<LockToken> unlock(Set<LockToken> tokens) { return heldLocks.unlock(tokens); }
public Set<LockToken> refresh(Set<LockToken> tokens) { return filter(tokens, HeldLocks::refresh); }
/** * Shuts down the lock service, and fails any outstanding requests with a {@link * com.palantir.leader.NotCurrentLeaderException}. */ @Override public void close() { reaperExecutor.shutdown(); heldLocks.failAllOutstandingRequestsWithNotCurrentLeaderException(); } }
public static AsyncLockService createDefault( LockLog lockLog, ScheduledExecutorService reaperExecutor, ScheduledExecutorService timeoutExecutor) { return new AsyncLockService( new LockCollection(), new ImmutableTimestampTracker(), new LockAcquirer(lockLog, timeoutExecutor), new HeldLocksCollection(), new AwaitedLocksCollection(), reaperExecutor); }
public void removeExpired() { Iterator<AsyncResult<HeldLocks>> iterator = heldLocksById.values().iterator(); while (iterator.hasNext()) { AsyncResult<HeldLocks> lockResult = iterator.next(); if (shouldRemove(lockResult)) { iterator.remove(); } } }
@Test public void successfulUnlockRemovesHeldLocks() { LockToken token = mockRefreshableRequest(); heldLocksCollection.unlock(ImmutableSet.of(token)); assertThat(heldLocksCollection.heldLocksById.isEmpty()).isTrue(); }
public Set<LockToken> unlock(Set<LockToken> tokens) { Set<LockToken> unlocked = filter(tokens, HeldLocks::unlock); for (LockToken token : unlocked) { heldLocksById.remove(token.getRequestId()); } return unlocked; }
/** * Shuts down the lock service, and fails any outstanding requests with a {@link * com.palantir.leader.NotCurrentLeaderException}. */ @Override public void close() { reaperExecutor.shutdown(); heldLocks.failAllOutstandingRequestsWithNotCurrentLeaderException(); } }
public static AsyncLockService createDefault( LockLog lockLog, ScheduledExecutorService reaperExecutor, ScheduledExecutorService timeoutExecutor) { return new AsyncLockService( new LockCollection(), new ImmutableTimestampTracker(), new LockAcquirer(lockLog, timeoutExecutor), new HeldLocksCollection(), new AwaitedLocksCollection(), reaperExecutor); }
public void removeExpired() { Iterator<AsyncResult<HeldLocks>> iterator = heldLocksById.values().iterator(); while (iterator.hasNext()) { AsyncResult<HeldLocks> lockResult = iterator.next(); if (shouldRemove(lockResult)) { iterator.remove(); } } }
public AsyncResult<LockToken> lock(UUID requestId, Set<LockDescriptor> lockDescriptors, TimeLimit timeout) { return heldLocks.getExistingOrAcquire( requestId, () -> acquireLocks(requestId, lockDescriptors, timeout)); }
@Test public void removesTimedOutRequests() { mockTimedOutRequest(); assertThat(heldLocksCollection.heldLocksById.size()).isEqualTo(1); heldLocksCollection.removeExpired(); assertThat(heldLocksCollection.heldLocksById.size()).isEqualTo(0); }
@Test public void unlockReturnsSubsetOfUnlockedLocks() { LockToken refreshableRequest = mockRefreshableRequest(); LockToken nonRefreshableRequest = mockNonRefreshableRequest(); Set<LockToken> expected = ImmutableSet.of(refreshableRequest); Set<LockToken> actual = heldLocksCollection.unlock( ImmutableSet.of(refreshableRequest, nonRefreshableRequest)); assertThat(actual).isEqualTo(expected); }
@Test public void refreshReturnsSubsetOfUnlockedLocks() { LockToken unlockableRequest = mockRefreshableRequest(); LockToken nonUnlockableRequest = mockNonRefreshableRequest(); Set<LockToken> expected = ImmutableSet.of(unlockableRequest); Set<LockToken> actual = heldLocksCollection.refresh(ImmutableSet.of(unlockableRequest, nonUnlockableRequest)); assertThat(actual).isEqualTo(expected); }
public Set<LockToken> refresh(Set<LockToken> tokens) { return filter(tokens, HeldLocks::refresh); }
@Test public void doesNotCallSupplierForExistingRequest() { heldLocksCollection.getExistingOrAcquire(REQUEST_ID, () -> new AsyncResult<>()); Supplier<AsyncResult<HeldLocks>> supplier = mock(Supplier.class); heldLocksCollection.getExistingOrAcquire(REQUEST_ID, supplier); verifyNoMoreInteractions(supplier); }
@Test public void reaperDoesNotDieIfItEncountersAnException() { doThrow(new RuntimeException("test")).when(heldLocks).removeExpired(); triggerNextReaperIteration(); triggerNextReaperIteration(); verify(heldLocks, times(2)).removeExpired(); }