private com.palantir.lock.LockRequest toLegacyWaitForLocksRequest(Set<LockDescriptor> lockDescriptors) { SortedMap<LockDescriptor, LockMode> locks = buildLockMap(lockDescriptors, LockMode.READ); return com.palantir.lock.LockRequest.builder(locks).lockAndRelease().build(); }
@Override public LockRefreshToken lock(String client, String lockName) throws InterruptedException { LockDescriptor descriptor = StringLockDescriptor.of(lockName); LockRequest request = LockRequest.builder(ImmutableSortedMap.of(descriptor, LockMode.WRITE)) .doNotBlock() .build(); return lockService.lock(client, request); }
private com.palantir.lock.LockRequest toLegacyLockRequest(LockRequest request) { SortedMap<LockDescriptor, LockMode> locks = buildLockMap(request.getLockDescriptors(), LockMode.WRITE); return com.palantir.lock.LockRequest.builder(locks) .blockForAtMost(SimpleTimeDuration.of(request.getAcquireTimeoutMs(), TimeUnit.MILLISECONDS)) .build(); }
public void lockOrRefresh() throws InterruptedException { if (token != null) { Set<LockRefreshToken> refreshedTokens = lockService.refreshLockRefreshTokens(ImmutableList.of(token)); log.info("Refreshed an existing lock token for {} in a single lock service (token {}); got {}", getLockIdLoggingArg(), SafeArg.of("existingLockToken", token), SafeArg.of("refreshedTokens", refreshedTokens)); if (refreshedTokens.isEmpty()) { token = null; } } else { LockDescriptor lock = StringLockDescriptor.of(lockId); LockRequest request = LockRequest.builder( ImmutableSortedMap.of(lock, LockMode.WRITE)).doNotBlock().build(); token = lockService.lock(LockClient.ANONYMOUS.getClientId(), request); log.info("Attempted to acquire the lock {} in a single lock service; got {}", getLockIdLoggingArg(), SafeArg.of("acquiredToken", token)); } }
private LockRefreshToken mockImmutableTsLockResponse() throws InterruptedException { LockDescriptor descriptor = AtlasTimestampLockDescriptor.of(FRESH_TIMESTAMP); com.palantir.lock.LockRequest expectedRequest = com.palantir.lock.LockRequest.builder(ImmutableSortedMap.of(descriptor, LockMode.READ)) .withLockedInVersionId(FRESH_TIMESTAMP).build(); LockRefreshToken expectedToken = new LockRefreshToken(BigInteger.ONE, 123L); when(lockService.lock(LOCK_CLIENT.getClientId(), expectedRequest)).thenReturn(expectedToken); return expectedToken; }
@Test public void waitForLocksDelegatesToLockService() throws InterruptedException { com.palantir.lock.LockRequest legacyRequest = com.palantir.lock.LockRequest.builder(buildLockMap(LockMode.READ)).lockAndRelease().build(); when(lockService.lock(LockClient.ANONYMOUS.getClientId(), legacyRequest)).thenReturn(LOCK_REFRESH_TOKEN); timelock.waitForLocks(WaitForLocksRequest.of(ImmutableSet.of(LOCK_A, LOCK_B), TIMEOUT)); verify(lockService).lock(LockClient.ANONYMOUS.getClientId(), legacyRequest); }
@Test public void testSimpleRefresh() throws InterruptedException { Builder builder = LockRequest.builder(ImmutableSortedMap.of(lock1, LockMode.WRITE)); builder.timeoutAfter(SimpleTimeDuration.of(5, TimeUnit.SECONDS)); LockResponse lock = server.lockWithFullLockResponse(LockClient.ANONYMOUS, builder.build()); Thread.sleep(10000); Set<HeldLocksToken> refreshTokens = server.refreshTokens(ImmutableList.of(lock.getToken())); Assert.assertEquals(1, refreshTokens.size()); } }
@Test public void lockDelegatesToLockService() throws InterruptedException { com.palantir.lock.LockRequest legacyRequest = com.palantir.lock.LockRequest.builder(buildLockMap(LockMode.WRITE)) .blockForAtMost(SimpleTimeDuration.of(TIMEOUT, TimeUnit.MILLISECONDS)) .build(); when(lockService.lock(LockClient.ANONYMOUS.getClientId(), legacyRequest)).thenReturn(LOCK_REFRESH_TOKEN); assertEquals(LockResponse.successful(LOCK_TOKEN_V2), timelock.lock( LockRequest.of(ImmutableSet.of(LOCK_A, LOCK_B), TIMEOUT))); verify(lockService).lock(LockClient.ANONYMOUS.getClientId(), legacyRequest); }
private void testReentrancy(LockMode mode1, LockMode mode2) throws InterruptedException { LockResponse lockResponse1 = server.lockWithFullLockResponse( client, LockRequest.builder(ImmutableSortedMap.of(lock1, mode1)).build()); LockResponse lockResponse2 = server.lockWithFullLockResponse( client, LockRequest.builder(ImmutableSortedMap.of(lock1, mode2)).build()); server.unlockSimple(SimpleHeldLocksToken.fromHeldLocksToken(lockResponse1.getToken())); server.unlockSimple(SimpleHeldLocksToken.fromHeldLocksToken(lockResponse2.getToken())); } }
@Test public void resilientToValidJsonBodyThatIsNotASerializableError() throws JsonProcessingException { LockRequest lockRequest = LockRequest.builder(ImmutableSortedMap.of(StringLockDescriptor.of(LOCK_ID), LockMode.WRITE)) .build(); Response response = createResponseForEntity(lockRequest); assertCanDecodeRuntimeException(response); }
/** Tests lockAndRelease with perf optimization */ @Test public void testLockAndRelease2() throws Exception { LockRequest hasLock1 = LockRequest.builder(ImmutableSortedMap.of(lock1, LockMode.WRITE)).build(); LockRequest hasLock2 = LockRequest.builder(ImmutableSortedMap.of(lock2, LockMode.WRITE)).build(); final LockRequest request = LockRequest.builder(ImmutableSortedMap.of(lock1, LockMode.WRITE, lock2, LockMode.WRITE)).lockAndRelease().build(); LockResponse resp2 = server.lockWithFullLockResponse(LockClient.ANONYMOUS, hasLock2); Assert.assertTrue(resp2.success()); Future<?> future = executor.submit((Callable<Void>) () -> { LockResponse resp = server.lockWithFullLockResponse(LockClient.ANONYMOUS, request); Assert.assertNotNull(resp); Assert.assertTrue(resp.success()); return null; }); Thread.sleep(10); try { future.get(1, TimeUnit.MILLISECONDS); Assert.fail(); } catch (TimeoutException e) { // good } LockResponse resp1 = server.lockWithFullLockResponse(client, hasLock1); server.unlock(resp2.getToken()); future.get(150, TimeUnit.SECONDS); server.unlock(resp1.getToken()); resp2 = server.lockWithFullLockResponse(LockClient.ANONYMOUS, hasLock2); server.unlock(resp2.getToken()); }
/** Tests lockAndRelease */ @Test public void testLockAndRelease() throws Exception { LockRequest hasLock2 = LockRequest.builder(ImmutableSortedMap.of(lock2, LockMode.WRITE)).build(); final LockRequest request = LockRequest.builder(ImmutableSortedMap.of(lock1, LockMode.WRITE, lock2, LockMode.WRITE)).lockAndRelease().build(); LockResponse resp2 = server.lockWithFullLockResponse(LockClient.ANONYMOUS, hasLock2); Assert.assertTrue(resp2.success()); Future<?> future = executor.submit((Callable<Void>) () -> { LockResponse resp = server.lockWithFullLockResponse(LockClient.ANONYMOUS, request); Assert.assertNotNull(resp); Assert.assertTrue(resp.success()); return null; }); try { future.get(1, TimeUnit.MILLISECONDS); Assert.fail(); } catch (TimeoutException e) { // good } server.unlock(resp2.getToken()); future.get(150, TimeUnit.SECONDS); resp2 = server.lockWithFullLockResponse(LockClient.ANONYMOUS, hasLock2); server.unlock(resp2.getToken()); }
@Override public LockImmutableTimestampResponse lockImmutableTimestamp(IdentifiedTimeLockRequest request) { long immutableLockTs = timestampService.getFreshTimestamp(); LockDescriptor lockDesc = AtlasTimestampLockDescriptor.of(immutableLockTs); com.palantir.lock.LockRequest lockRequest = com.palantir.lock.LockRequest.builder( ImmutableSortedMap.of(lockDesc, LockMode.READ)) .withLockedInVersionId(immutableLockTs).build(); LockRefreshToken lock; try { lock = lockService.lock(immutableTsLockClient.getClientId(), lockRequest); } catch (InterruptedException e) { throw Throwables.throwUncheckedException(e); } try { return LockImmutableTimestampResponse.of( getImmutableTimestampInternal(immutableLockTs), LockTokenConverter.toTokenV2(lock)); } catch (Throwable e) { if (lock != null) { lockService.unlock(lock); } throw Throwables.rewrapAndThrowUncheckedException(e); } }
LockClient clientB = LockClient.of("Client B"); LockRequest request1 = LockRequest.builder( LockCollections.of(ImmutableSortedMap.of(DESCRIPTOR_1, LockMode.WRITE))) .blockForAtMost(SimpleTimeDuration.of(1000, TimeUnit.MILLISECONDS)) .build(); LockRequest request2 = LockRequest.builder( LockCollections.of(ImmutableSortedMap.of(DESCRIPTOR_2, LockMode.WRITE))) .blockForAtMost(SimpleTimeDuration.of(1000, TimeUnit.MILLISECONDS))
/** Convert a write lock to a read lock */ @Test public void testConvertWriteToRead() throws Exception { final LockRequest request1 = LockRequest.builder(ImmutableSortedMap.of(lock1, LockMode.WRITE)) .build(); final LockRequest request2 = LockRequest.builder(ImmutableSortedMap.of(lock1, LockMode.READ)) .build(); HeldLocksToken token1 = server.lockWithFullLockResponse(client, request1).getToken(); Assert.assertNotNull(token1); Assert.assertEquals(client, token1.getClient()); Assert.assertEquals(request1.getLockDescriptors(), token1.getLockDescriptors()); Future<?> future = executor.submit((Callable<Void>) () -> { barrier.await(); HeldLocksToken validToken = server.lockWithFullLockResponse(LockClient.ANONYMOUS, request2).getToken(); Assert.assertNotNull(validToken); Assert.assertEquals(LockClient.ANONYMOUS, validToken.getClient()); Assert.assertEquals(request2.getLockDescriptors(), validToken.getLockDescriptors()); Assert.assertTrue(server.unlock(validToken)); return null; }); barrier.await(); Thread.sleep(50); HeldLocksToken token2 = server.lockWithFullLockResponse(client, request2).getToken(); Assert.assertNotNull(token2); Assert.assertEquals(client, token2.getClient()); Assert.assertEquals(request2.getLockDescriptors(), token2.getLockDescriptors()); Assert.assertTrue(server.unlock(token1)); future.get(); Assert.assertTrue(server.unlock(token2)); Assert.assertTrue(server.getTokens(client).isEmpty()); }
LockRequest.Builder newRequest = LockRequest.builder(request.getLockDescriptors()); newRequest.doNotBlock(); newRequest.timeoutAfter(request.getLockTimeout());
LockRequest request1 = LockRequest.builder(ImmutableSortedMap.of(lock1, LockMode.WRITE)) .doNotBlock().build(); LockRequest request2 = LockRequest.builder(ImmutableSortedMap.of(lock2, LockMode.READ)) .doNotBlock().build(); Assert.assertEquals(request2.getLockDescriptors(), token2.getLockDescriptors()); LockRequest request3 = LockRequest.builder( ImmutableSortedMap.of(lock1, LockMode.READ, lock2, LockMode.WRITE)) .lockAsManyAsPossible()
@Test public void setsGlobalDefaultLockTimeout() { TimeDuration expectedTimeout = SimpleTimeDuration.of(47, TimeUnit.SECONDS); AtlasDbConfig atlasDbConfig = ImmutableAtlasDbConfig.builder() .keyValueService(new InMemoryAtlasDbConfig()) .defaultLockTimeoutSeconds((int) expectedTimeout.getTime()) .build(); TransactionManagers.builder() .config(atlasDbConfig) .userAgent("test") .globalMetricsRegistry(new MetricRegistry()) .globalTaggedMetricRegistry(DefaultTaggedMetricRegistry.getDefault()) .registrar(environment) .build() .serializable(); assertEquals(expectedTimeout, LockRequest.getDefaultLockTimeout()); LockRequest lockRequest = LockRequest .builder(ImmutableSortedMap.of(StringLockDescriptor.of("foo"), LockMode.WRITE)).build(); assertEquals(expectedTimeout, lockRequest.getLockTimeout()); }
private void runAndVerifyCli(Verifier verifier) throws Exception { try (SingleBackendCliTestRunner runner = makeRunner(cliArgs.toArray(new String[0]))) { TestAtlasDbServices services = runner.connect(moduleFactory); LockService lockService = services.getLockService(); TimestampService tss = services.getTimestampService(); LockClient client = services.getTestLockClient(); Clock clock = GlobalClock.create(lockService); long prePunch = clock.getTimeMillis(); punch(services, tss, clock); long postPunch = clock.getTimeMillis(); long immutableTs = tss.getFreshTimestamp(); LockRequest request = LockRequest.builder(ImmutableSortedMap.of(lock, LockMode.WRITE)) .withLockedInVersionId(immutableTs) .doNotBlock() .build(); LockRefreshToken token = lockService.lock(client.getClientId(), request); long lastFreshTs = tss.getFreshTimestamps(1000).getUpperBound(); verifier.verify(runner, tss, immutableTs, prePunch, postPunch, lastFreshTs, true); lockService.unlock(token); lastFreshTs = tss.getFreshTimestamps(1000).getUpperBound(); // there are no locks so we now expect immutable to just be a fresh runner.freshCommand(); verifier.verify(runner, tss, immutableTs, prePunch, postPunch, lastFreshTs, false); } }
/** Tests that RemoteLockService api (that internal forwards to LockService api) passes a sanity check. */ @Test public void testRemoteLockServiceApi() throws InterruptedException { LockRequest request = LockRequest.builder(ImmutableSortedMap.of( lock1, LockMode.READ, lock2, LockMode.WRITE)) .withLockedInVersionId(10).doNotBlock().build(); Assert.assertNull(server.getMinLockedInVersionId(LockClient.ANONYMOUS.getClientId())); LockRefreshToken token = server.lock(LockClient.ANONYMOUS.getClientId(), request); Assert.assertEquals(10, (long) server.getMinLockedInVersionId(LockClient.ANONYMOUS.getClientId())); Assert.assertNull(server.lock(LockClient.ANONYMOUS.getClientId(), request)); server.unlock(token); Assert.assertNull(server.getMinLockedInVersionId(LockClient.ANONYMOUS.getClientId())); HeldLocksToken heldToken = server.lockAndGetHeldLocks(LockClient.ANONYMOUS.getClientId(), request); Assert.assertEquals(10, (long) server.getMinLockedInVersionId(LockClient.ANONYMOUS.getClientId())); Assert.assertNull(server.lockAndGetHeldLocks(LockClient.ANONYMOUS.getClientId(), request)); server.unlock(heldToken.getLockRefreshToken()); }