use of java.util.concurrent.CancellationException in project etcd-java by IBM.
the class PersistentLeaseKey method putKey.
// called only from our serialized executor context
protected void putKey(long leaseId) {
if (leaseId == 0L || closeFuture != null)
return;
if (updateFuture != null && !updateFuture.isDone()) {
// if the cancellation wins then putKey will be immediately retried
updateFuture.cancel(false);
return;
}
// execute a transaction which either sets the lease on an existing key
// or creates the key with the lease if it doesn't exist
PutRequest.Builder putBld = PutRequest.newBuilder().setKey(key).setLease(leaseId);
KvClient.FluentTxnRequest req = client.getKvClient().txnIf().exists(key).backoffRetry(() -> closeFuture == null && isActive());
ListenableFuture<? extends Object> fut;
ListenableFuture<TxnResponse> txnFut;
if (rangeCache == null) {
fut = txnFut = req.then().put(putBld.setIgnoreValue(true)).elseDo().put(putBld.setIgnoreValue(false).setValue(defaultValue)).async();
} else {
RangeRequest getOp = RangeRequest.newBuilder().setKey(key).build();
txnFut = req.then().put(putBld.setIgnoreValue(true)).get(getOp).elseDo().put(putBld.setIgnoreValue(false).setValue(defaultValue)).get(getOp).async();
fut = Futures.transform(txnFut, (Function<TxnResponse, Object>) tr -> rangeCache.offerUpdate(tr.getResponses(1).getResponseRange().getKvs(0), false));
}
if (!isDone())
fut = Futures.transform(fut, (Function<Object, Object>) r -> set(key));
// this callback is to trigger an immediate retry in case the attempt was cancelled by a more
// recent lease state change to active
Futures.addCallback(fut, (FutureListener<Object>) (v, t) -> {
if (t instanceof CancellationException && isActive())
putKey(leaseId);
}, executor);
updateFuture = fut;
}
use of java.util.concurrent.CancellationException in project bookkeeper by apache.
the class ZKDistributedLock method asyncAcquire.
/**
* Asynchronously acquire the lock. Technically the try phase of this operation--which adds us to the waiter
* list--is executed synchronously, but the lock wait itself doesn't block.
*/
@Override
public synchronized CompletableFuture<ZKDistributedLock> asyncAcquire() {
if (null != lockAcquireFuture) {
return FutureUtils.exception(new UnexpectedException("Someone is already acquiring/acquired lock " + lockPath));
}
final CompletableFuture<ZKDistributedLock> promise = FutureUtils.createFuture();
promise.whenComplete((zkDistributedLock, throwable) -> {
if (null == throwable || !(throwable instanceof CancellationException)) {
return;
}
lockStateExecutor.executeOrdered(lockPath, () -> asyncClose());
});
final Stopwatch stopwatch = Stopwatch.createStarted();
promise.whenComplete(new FutureEventListener<ZKDistributedLock>() {
@Override
public void onSuccess(ZKDistributedLock lock) {
acquireStats.registerSuccessfulEvent(stopwatch.stop().elapsed(TimeUnit.MICROSECONDS), TimeUnit.MICROSECONDS);
}
@Override
public void onFailure(Throwable cause) {
acquireStats.registerFailedEvent(stopwatch.stop().elapsed(TimeUnit.MICROSECONDS), TimeUnit.MICROSECONDS);
// release the lock if fail to acquire
asyncClose();
}
});
this.lockAcquireFuture = promise;
lockStateExecutor.executeOrdered(lockPath, () -> doAsyncAcquireWithSemaphore(promise, lockTimeout));
return promise;
}
use of java.util.concurrent.CancellationException in project bookkeeper by apache.
the class ZKSessionLockFactory method createLock.
@Override
public CompletableFuture<SessionLock> createLock(String lockPath, DistributedLockContext context) {
AtomicInteger numRetries = new AtomicInteger(lockCreationRetries);
final AtomicReference<Throwable> interruptedException = new AtomicReference<Throwable>(null);
CompletableFuture<SessionLock> createPromise = FutureUtils.createFuture();
createPromise.whenComplete((value, cause) -> {
if (null != cause && cause instanceof CancellationException) {
interruptedException.set(cause);
}
});
createLock(lockPath, context, interruptedException, numRetries, createPromise, 0L);
return createPromise;
}
use of java.util.concurrent.CancellationException in project bookkeeper by apache.
the class TestAsyncReaderLock method testReaderLockFutureCancelledWhileWaiting.
@Test(timeout = 60000)
public void testReaderLockFutureCancelledWhileWaiting() throws Exception {
String name = runtime.getMethodName();
DistributedLogManager dlm0 = createNewDLM(conf, name);
BKAsyncLogWriter writer = (BKAsyncLogWriter) (dlm0.startAsyncLogSegmentNonPartitioned());
writer.write(DLMTestUtil.getLogRecordInstance(1L));
writer.write(DLMTestUtil.getLogRecordInstance(2L));
writer.closeAndComplete();
DistributedLogManager dlm1 = createNewDLM(conf, name);
CompletableFuture<AsyncLogReader> futureReader1 = dlm1.getAsyncLogReaderWithLock(DLSN.InitialDLSN);
AsyncLogReader reader1 = Utils.ioResult(futureReader1);
DistributedLogManager dlm2 = createNewDLM(conf, name);
CompletableFuture<AsyncLogReader> futureReader2 = dlm2.getAsyncLogReaderWithLock(DLSN.InitialDLSN);
try {
futureReader2.cancel(true);
Utils.ioResult(futureReader2);
fail("Should fail getting log reader as it is cancelled");
} catch (CancellationException ce) {
} catch (LockClosedException ex) {
} catch (LockCancelledException ex) {
} catch (OwnershipAcquireFailedException oafe) {
}
futureReader2 = dlm2.getAsyncLogReaderWithLock(DLSN.InitialDLSN);
Utils.close(reader1);
Utils.ioResult(futureReader2);
dlm0.close();
dlm1.close();
dlm2.close();
}
use of java.util.concurrent.CancellationException in project bookkeeper by apache.
the class ZKLogStreamMetadataStore method ensureReadLockPathExist.
//
// Create Read Lock
//
private CompletableFuture<Void> ensureReadLockPathExist(final LogMetadata logMetadata, final String readLockPath) {
final CompletableFuture<Void> promise = new CompletableFuture<Void>();
promise.whenComplete((value, cause) -> {
if (cause instanceof CancellationException) {
FutureUtils.completeExceptionally(promise, new LockCancelledException(readLockPath, "Could not ensure read lock path", cause));
}
});
Optional<String> parentPathShouldNotCreate = Optional.of(logMetadata.getLogRootPath());
Utils.zkAsyncCreateFullPathOptimisticRecursive(zooKeeperClient, readLockPath, parentPathShouldNotCreate, new byte[0], zooKeeperClient.getDefaultACL(), CreateMode.PERSISTENT, new org.apache.zookeeper.AsyncCallback.StringCallback() {
@Override
public void processResult(final int rc, final String path, Object ctx, String name) {
if (KeeperException.Code.NONODE.intValue() == rc) {
FutureUtils.completeExceptionally(promise, new LogNotFoundException(String.format("Log %s does not exist or has been deleted", logMetadata.getFullyQualifiedName())));
} else if (KeeperException.Code.OK.intValue() == rc) {
FutureUtils.complete(promise, null);
LOG.trace("Created path {}.", path);
} else if (KeeperException.Code.NODEEXISTS.intValue() == rc) {
FutureUtils.complete(promise, null);
LOG.trace("Path {} is already existed.", path);
} else if (DistributedLogConstants.ZK_CONNECTION_EXCEPTION_RESULT_CODE == rc) {
FutureUtils.completeExceptionally(promise, new ZooKeeperClient.ZooKeeperConnectionException(path));
} else if (DistributedLogConstants.DL_INTERRUPTED_EXCEPTION_RESULT_CODE == rc) {
FutureUtils.completeExceptionally(promise, new DLInterruptedException(path));
} else {
FutureUtils.completeExceptionally(promise, KeeperException.create(KeeperException.Code.get(rc)));
}
}
}, null);
return promise;
}
Aggregations