@Override @Nullable public LockRefreshToken apply(@Nullable HeldLocksToken input) { return input.getLockRefreshToken(); } };
@JsonIgnore @Nullable public LockRefreshToken getLockRefreshToken() { return token == null ? null : token.getLockRefreshToken(); }
@Override public void throwIfConditionInvalid(long timestamp) { if (lockService.refreshLockRefreshTokens(Collections.singleton(heldLock.getLockRefreshToken())).isEmpty()) { log.warn("Lock service locks were no longer valid", UnsafeArg.of("invalidToken", heldLock.getLockRefreshToken())); throw new TransactionLockTimeoutException("Provided transaction lock expired. Token: " + heldLock.getLockRefreshToken()); } }
@Override public boolean unlock(HeldLocksToken token) { toRefresh.remove(token.getLockRefreshToken()); return super.unlock(token); }
@Override public boolean unlockAndFreeze(HeldLocksToken token) { toRefresh.remove(token.getLockRefreshToken()); return super.unlockAndFreeze(token); }
@Override public HeldLocksToken lockAndGetHeldLocks(String client, LockRequest request) throws InterruptedException { HeldLocksToken lock = super.lockAndGetHeldLocks(client, request); if (lock != null) { toRefresh.add(lock.getLockRefreshToken()); } return lock; }
@Override public HeldLocksToken lockAndGetHeldLocks(String client, LockRequest request) throws InterruptedException { HeldLocksToken ret = super.lockAndGetHeldLocks(client, request); if (ret != null) { toRefresh.add(ret.getLockRefreshToken()); } return ret; }
@Override public void throwIfConditionInvalid(long timestamp) { if (lockTokens.isEmpty()) { return; } Set<LockRefreshToken> refreshTokens = lockTokens.stream() .map(HeldLocksToken::getLockRefreshToken) .collect(Collectors.toSet()); Set<LockRefreshToken> refreshedLocks = lockService.refreshLockRefreshTokens(refreshTokens); Set<LockRefreshToken> expiredLocks = Sets.difference(refreshTokens, refreshedLocks); if (!expiredLocks.isEmpty()) { List<HeldLocksToken> expiredHeldLocks = lockTokens.stream() .filter(token -> expiredLocks.contains(token.getLockRefreshToken())) .collect(Collectors.toList()); log.warn("External lock service locks were no longer valid", UnsafeArg.of("invalidLocks", expiredHeldLocks)); throw new TransactionLockTimeoutNonRetriableException("Provided external lock tokens expired. " + "Retry is not possible. Locks: " + expiredHeldLocks); } }
@Override public void cleanup() { PreCommitConditions.runCleanupTask(() -> lockService.unlock(heldLock.getLockRefreshToken())); }
@Override public LockResponse lockWithFullLockResponse(LockClient client, LockRequest request) throws InterruptedException { LockResponse lock = super.lockWithFullLockResponse(client, request); if (lock.getToken() != null) { toRefresh.add(lock.getToken().getLockRefreshToken()); } return lock; }
@Override @Nullable public LockRefreshToken apply(@Nullable HeldLocksToken input) { return input.getLockRefreshToken(); } };
@JsonIgnore @Nullable public LockRefreshToken getLockRefreshToken() { return token == null ? null : token.getLockRefreshToken(); }
@Override public HeldLocksToken lockAndGetHeldLocks(String client, LockRequest request) throws InterruptedException { HeldLocksToken ret = super.lockAndGetHeldLocks(client, request); if (ret != null) { toRefresh.add(ret.getLockRefreshToken()); } return ret; }
@Override public HeldLocksToken lockAndGetHeldLocks(String client, LockRequest request) throws InterruptedException { HeldLocksToken lock = super.lockAndGetHeldLocks(client, request); if (lock != null) { toRefresh.add(lock.getLockRefreshToken()); } return lock; }
@Override public boolean unlock(HeldLocksToken token) { toRefresh.remove(token.getLockRefreshToken()); return super.unlock(token); }
@Override public boolean unlockAndFreeze(HeldLocksToken token) { toRefresh.remove(token.getLockRefreshToken()); return super.unlockAndFreeze(token); }
@Override public void throwIfConditionInvalid(long timestamp) { if (lockService.refreshLockRefreshTokens(Collections.singleton(heldLock.getLockRefreshToken())).isEmpty()) { log.warn("Lock service locks were no longer valid", UnsafeArg.of("invalidToken", heldLock.getLockRefreshToken())); throw new TransactionLockTimeoutException("Provided transaction lock expired. Token: " + heldLock.getLockRefreshToken()); } }
@Override public void cleanup() { PreCommitConditions.runCleanupTask(() -> lockService.unlock(heldLock.getLockRefreshToken())); }
@Override public LockResponse lockWithFullLockResponse(LockClient client, LockRequest request) throws InterruptedException { LockResponse lock = super.lockWithFullLockResponse(client, request); if (lock.getToken() != null) { toRefresh.add(lock.getToken().getLockRefreshToken()); } return lock; }
/** 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()); }