DynoLockClient { public void releaseLock(String resource) { if (!checkResourceExists(resource)) { logger.info("No lock held on {}", resource); return; } CountDownLatch latch = new CountDownLatch(votingHostsSelector.getVotingSize()); votingHostsSelector.getVotingHosts().getEntireList().stream() .map(host -> new CheckAndRunHost(host, pool, "del", resource, resourceKeyMap.get(resource))) .forEach(ulH -> CompletableFuture.supplyAsync(ulH, service) .thenAccept(result -> latch.countDown()) ); boolean latchValue = false; try { latchValue = latch.await(timeout, timeoutUnit); } catch (InterruptedException e) { logger.info("Interrupted while releasing the lock for resource {}", resource); } if (latchValue) { logger.info("Released lock on {}", resource); } else { logger.info("Timed out before we could release the lock"); } resourceKeyMap.remove(resource); } DynoLockClient(ConnectionPool pool, VotingHostsSelector votingHostsSelector, long timeout, TimeUnit unit); void setTimeoutUnit(TimeUnit timeoutUnit); void setTimeout(long timeout); List<String> getLockedResources(); void releaseLock(String resource); boolean acquireLock(String resource, long ttlMS, Consumer<String> failure); long acquireLock(String resource, long ttlMS); long checkLock(String resource); long extendLock(String resource, long ttlMS); void cleanup(); void logLocks();  }
@Test public void testReleaseLock() { long v = dynoLockClient.acquireLock(resource, 100); Assert.assertTrue("Acquire lock did not succeed in time", v > 0); dynoLockClient.releaseLock(resource); v = dynoLockClient.checkLock(resource); Assert.assertTrue("Release lock failed",v == 0); }