List of usage examples for java.util.concurrent CompletableFuture completeExceptionally
public boolean completeExceptionally(Throwable ex)
From source file:org.apache.distributedlog.impl.ZKLogMetadataStore.java
@Override public CompletableFuture<Iterator<String>> getLogs(String logNamePrefix) { final CompletableFuture<Iterator<String>> promise = new CompletableFuture<Iterator<String>>(); final String nsRootPath; if (StringUtils.isEmpty(logNamePrefix)) { nsRootPath = namespace.getPath(); } else {/*from w w w . j a v a 2s . co m*/ nsRootPath = namespace.getPath() + "/" + logNamePrefix; } try { final ZooKeeper zk = zkc.get(); zk.sync(nsRootPath, new AsyncCallback.VoidCallback() { @Override public void processResult(int syncRc, String syncPath, Object ctx) { if (KeeperException.Code.OK.intValue() == syncRc) { zk.getChildren(nsRootPath, false, new AsyncCallback.Children2Callback() { @Override public void processResult(int rc, String path, Object ctx, List<String> children, Stat stat) { if (KeeperException.Code.OK.intValue() == rc) { List<String> results = Lists.newArrayListWithExpectedSize(children.size()); for (String child : children) { if (!isReservedStreamName(child)) { results.add(child); } } promise.complete(results.iterator()); } else if (KeeperException.Code.NONODE.intValue() == rc) { List<String> streams = Lists.newLinkedList(); promise.complete(streams.iterator()); } else { promise.completeExceptionally(new ZKException( "Error reading namespace " + nsRootPath, KeeperException.Code.get(rc))); } } }, null); } else if (KeeperException.Code.NONODE.intValue() == syncRc) { List<String> streams = Lists.newLinkedList(); promise.complete(streams.iterator()); } else { promise.completeExceptionally(new ZKException("Error reading namespace " + nsRootPath, KeeperException.Code.get(syncRc))); } } }, null); zkc.get(); } catch (ZooKeeperClient.ZooKeeperConnectionException e) { promise.completeExceptionally(e); } catch (InterruptedException e) { Thread.currentThread().interrupt(); promise.completeExceptionally(e); } return promise; }
From source file:org.apache.distributedlog.lock.ZKSessionLock.java
/** * Execute a lock action of a given <i>lockEpoch</i> in ordered safe way. If the lock action couln't be * executed due to epoch changed, fail the given <i>promise</i> with * {@link EpochChangedException}//from w w w . j av a 2 s.c o m * * @param lockEpoch * lock epoch * @param func * function to execute a lock action * @param promise * promise */ protected <T> void executeLockAction(final int lockEpoch, final LockAction func, final CompletableFuture<T> promise) { lockStateExecutor.executeOrdered(lockPath, new SafeRunnable() { @Override public void safeRun() { int currentEpoch = getEpoch(); if (currentEpoch == lockEpoch) { if (LOG.isTraceEnabled()) { LOG.trace("{} executed lock action '{}' under epoch {} for lock {}", new Object[] { lockId, func.getActionName(), lockEpoch, lockPath }); } func.execute(); if (LOG.isTraceEnabled()) { LOG.trace("{} executed lock action '{}' under epoch {} for lock {}", new Object[] { lockId, func.getActionName(), lockEpoch, lockPath }); } } else { if (LOG.isTraceEnabled()) { LOG.trace( "{} skipped executing lock action '{}' for lock {}," + " since epoch is changed from {} to {}.", new Object[] { lockId, func.getActionName(), lockPath, lockEpoch, currentEpoch }); } promise.completeExceptionally(new EpochChangedException(lockPath, lockEpoch, currentEpoch)); } } }); }
From source file:org.apache.distributedlog.lock.ZKSessionLock.java
/** * Get client id and its ephemeral owner. * * @param zkClient//from w w w .j a v a2s .co m * zookeeper client * @param lockPath * lock path * @param nodeName * node name * @return client id and its ephemeral owner. */ static CompletableFuture<Pair<String, Long>> asyncParseClientID(ZooKeeper zkClient, String lockPath, String nodeName) { String[] parts = nodeName.split("_"); // member_<clientid>_s<owner_session>_ if (4 == parts.length && parts[2].startsWith("s")) { long sessionOwner = Long.parseLong(parts[2].substring(1)); String clientId; try { clientId = URLDecoder.decode(parts[1], UTF_8.name()); return FutureUtils.value(Pair.of(clientId, sessionOwner)); } catch (UnsupportedEncodingException e) { // if failed to parse client id, we have to get client id by zookeeper#getData. } } final CompletableFuture<Pair<String, Long>> promise = new CompletableFuture<Pair<String, Long>>(); zkClient.getData(lockPath + "/" + nodeName, false, new AsyncCallback.DataCallback() { @Override public void processResult(int rc, String path, Object ctx, byte[] data, Stat stat) { if (KeeperException.Code.OK.intValue() != rc) { promise.completeExceptionally(KeeperException.create(KeeperException.Code.get(rc))); } else { promise.complete(Pair.of(deserializeClientId(data), stat.getEphemeralOwner())); } } }, null); return promise; }
From source file:org.apache.distributedlog.lock.ZKSessionLock.java
@Override public CompletableFuture<LockWaiter> asyncTryLock(final long timeout, final TimeUnit unit) { final CompletableFuture<String> result = new CompletableFuture<String>(); final boolean wait = DistributedLogConstants.LOCK_IMMEDIATE != timeout; if (wait) {/* w w w . j a va 2 s .c om*/ asyncTryLock(wait, result); } else { // try to check locks first zk.getChildren(lockPath, null, new AsyncCallback.Children2Callback() { @Override public void processResult(final int rc, String path, Object ctx, final List<String> children, Stat stat) { lockStateExecutor.executeOrdered(lockPath, new SafeRunnable() { @Override public void safeRun() { if (!lockState.inState(State.INIT)) { result.completeExceptionally(new LockStateChangedException(lockPath, lockId, State.INIT, lockState.getState())); return; } if (KeeperException.Code.OK.intValue() != rc) { result.completeExceptionally(KeeperException.create(KeeperException.Code.get(rc))); return; } FailpointUtils.checkFailPointNoThrow(FailpointUtils.FailPointName.FP_LockTryAcquire); Collections.sort(children, MEMBER_COMPARATOR); if (children.size() > 0) { asyncParseClientID(zk, lockPath, children.get(0)) .whenCompleteAsync(new FutureEventListener<Pair<String, Long>>() { @Override public void onSuccess(Pair<String, Long> owner) { if (!checkOrClaimLockOwner(owner, result)) { acquireFuture.complete(false); } } @Override public void onFailure(final Throwable cause) { result.completeExceptionally(cause); } }, lockStateExecutor.chooseThread(lockPath)); } else { asyncTryLock(wait, result); } } }); } }, null); } final CompletableFuture<Boolean> waiterAcquireFuture = FutureUtils.createFuture(); waiterAcquireFuture.whenComplete((value, cause) -> acquireFuture.completeExceptionally(cause)); return result.thenApply(new Function<String, LockWaiter>() { @Override public LockWaiter apply(final String currentOwner) { final Exception acquireException = new OwnershipAcquireFailedException(lockPath, currentOwner); FutureUtils.within(acquireFuture, timeout, unit, acquireException, lockStateExecutor, lockPath) .whenComplete(new FutureEventListener<Boolean>() { @Override public void onSuccess(Boolean acquired) { completeOrFail(acquireException); } @Override public void onFailure(final Throwable acquireCause) { completeOrFail(acquireException); } private void completeOrFail(final Throwable acquireCause) { if (isLockHeld()) { waiterAcquireFuture.complete(true); } else { asyncUnlock().whenComplete(new FutureEventListener<Void>() { @Override public void onSuccess(Void value) { waiterAcquireFuture.completeExceptionally(acquireCause); } @Override public void onFailure(Throwable cause) { waiterAcquireFuture.completeExceptionally(acquireCause); } }); } } }); return new LockWaiter(lockId.getLeft(), currentOwner, waiterAcquireFuture); } }); }
From source file:org.apache.distributedlog.lock.ZKSessionLock.java
private boolean checkOrClaimLockOwner(final Pair<String, Long> currentOwner, final CompletableFuture<String> result) { if (lockId.compareTo(currentOwner) != 0 && !lockContext.hasLockId(currentOwner)) { lockStateExecutor.executeOrdered(lockPath, new SafeRunnable() { @Override/*from w w w .j a v a 2s . co m*/ public void safeRun() { result.complete(currentOwner.getLeft()); } }); return false; } // current owner is itself final int curEpoch = epochUpdater.incrementAndGet(this); executeLockAction(curEpoch, new LockAction() { @Override public void execute() { if (!lockState.inState(State.INIT)) { result.completeExceptionally( new LockStateChangedException(lockPath, lockId, State.INIT, lockState.getState())); return; } asyncTryLock(false, result); } @Override public String getActionName() { return "claimOwnership(owner=" + currentOwner + ")"; } }, result); return true; }
From source file:org.apache.distributedlog.lock.ZKSessionLock.java
/** * Try lock. If it failed, it would cleanup its attempt. * * @param wait/*from w w w .jav a 2 s.c o m*/ * whether to wait for ownership. * @param result * promise to satisfy with current lock owner */ private void asyncTryLock(boolean wait, final CompletableFuture<String> result) { final CompletableFuture<String> lockResult = new CompletableFuture<String>(); lockResult.whenComplete(new FutureEventListener<String>() { @Override public void onSuccess(String currentOwner) { result.complete(currentOwner); } @Override public void onFailure(final Throwable lockCause) { // If tryLock failed due to state changed, we don't need to cleanup if (lockCause instanceof LockStateChangedException) { LOG.info("skipping cleanup for {} at {} after encountering lock " + "state change exception : ", new Object[] { lockId, lockPath, lockCause }); result.completeExceptionally(lockCause); return; } if (LOG.isDebugEnabled()) { LOG.debug("{} is cleaning up its lock state for {} due to : ", new Object[] { lockId, lockPath, lockCause }); } // If we encountered any exception we should cleanup CompletableFuture<Void> unlockResult = asyncUnlock(); unlockResult.whenComplete(new FutureEventListener<Void>() { @Override public void onSuccess(Void value) { result.completeExceptionally(lockCause); } @Override public void onFailure(Throwable cause) { result.completeExceptionally(lockCause); } }); } }); asyncTryLockWithoutCleanup(wait, lockResult); }
From source file:org.apache.distributedlog.lock.ZKSessionLock.java
/** * Try lock. If wait is true, it would wait and watch sibling to acquire lock when * the sibling is dead. <i>acquireCompletableFuture</i> will be notified either it locked successfully * or the lock failed. The promise will only satisfy with current lock owner. * * <p>NOTE: the <i>promise</i> is only satisfied on <i>lockStateExecutor</i>, so any * transformations attached on promise will be executed in order.</p> * * @param wait/*from w w w . j av a2s. com*/ * whether to wait for ownership. * @param promise * promise to satisfy with current lock owner. */ private void asyncTryLockWithoutCleanup(final boolean wait, final CompletableFuture<String> promise) { executeLockAction(getEpoch(), new LockAction() { @Override public void execute() { if (!lockState.inState(State.INIT)) { promise.completeExceptionally( new LockStateChangedException(lockPath, lockId, State.INIT, lockState.getState())); return; } lockState.transition(State.PREPARING); final int curEpoch = epochUpdater.incrementAndGet(ZKSessionLock.this); watcher = new LockWatcher(curEpoch); // register watcher for session expires zkClient.register(watcher); // Encode both client id and session in the lock node String myPath; try { // member_<clientid>_s<owner_session>_ myPath = getLockPathPrefixV3(lockPath, lockId.getLeft(), lockId.getRight()); } catch (UnsupportedEncodingException uee) { myPath = getLockPathPrefixV1(lockPath); } zk.create(myPath, serializeClientId(lockId.getLeft()), zkClient.getDefaultACL(), CreateMode.EPHEMERAL_SEQUENTIAL, new AsyncCallback.StringCallback() { @Override public void processResult(final int rc, String path, Object ctx, final String name) { executeLockAction(curEpoch, new LockAction() { @Override public void execute() { if (KeeperException.Code.OK.intValue() != rc) { KeeperException ke = KeeperException .create(KeeperException.Code.get(rc)); promise.completeExceptionally(ke); return; } if (FailpointUtils.checkFailPointNoThrow( FailpointUtils.FailPointName.FP_LockTryCloseRaceCondition)) { lockState.transition(State.CLOSING); lockState.transition(State.CLOSED); } if (null != currentNode) { LOG.error("Current node for {} overwritten current = {} new = {}", new Object[] { lockPath, lockId, getLockIdFromPath(currentNode) }); } currentNode = name; currentId = getLockIdFromPath(currentNode); LOG.trace("{} received member id for lock {}", lockId, currentId); if (lockState.isExpiredOrClosing()) { // Delete node attempt may have come after PREPARING but before create node, // in which case we'd be left with a dangling node unless we clean up. CompletableFuture<Void> deletePromise = new CompletableFuture<Void>(); deleteLockNode(deletePromise); FutureUtils .ensure(deletePromise, () -> promise.completeExceptionally( new LockClosedException(lockPath, lockId, lockState.getState()))); return; } lockState.transition(State.PREPARED); checkLockOwnerAndWaitIfPossible(watcher, wait, promise); } @Override public String getActionName() { return "postPrepare(wait=" + wait + ")"; } }); } }, null); } @Override public String getActionName() { return "prepare(wait=" + wait + ")"; } }, promise); }
From source file:org.apache.distributedlog.lock.ZKSessionLock.java
/** * Check Lock Owner Phase 2 : check all lock waiters to get current owner and wait for ownership if necessary. * * @param lockWatcher/*from www . j a v a 2s .c o m*/ * lock watcher. * @param wait * whether to wait for ownership. * @param getChildrenRc * result of getting all lock waiters * @param children * current lock waiters. * @param promise * promise to satisfy with current lock owner. */ private void processLockWaiters(final LockWatcher lockWatcher, final boolean wait, final int getChildrenRc, final List<String> children, final CompletableFuture<String> promise) { executeLockAction(lockWatcher.epoch, new LockAction() { @Override public void execute() { if (!lockState.inState(State.PREPARED)) { // e.g. lock closed or session expired after prepared promise.completeExceptionally( new LockStateChangedException(lockPath, lockId, State.PREPARED, lockState.getState())); return; } if (KeeperException.Code.OK.intValue() != getChildrenRc) { promise.completeExceptionally(KeeperException.create(KeeperException.Code.get(getChildrenRc))); return; } if (children.isEmpty()) { LOG.error("Error, member list is empty for lock {}.", lockPath); promise.completeExceptionally( new UnexpectedException("Empty member list for lock " + lockPath)); return; } // sort the children Collections.sort(children, MEMBER_COMPARATOR); final String cid = currentId; final int memberIndex = children.indexOf(cid); if (LOG.isDebugEnabled()) { LOG.debug("{} is the number {} member in the list.", cid, memberIndex); } // If we hold the lock if (memberIndex == 0) { LOG.info("{} acquired the lock {}.", cid, lockPath); claimOwnership(lockWatcher.epoch); promise.complete(cid); } else if (memberIndex > 0) { // we are in the member list but we didn't hold the lock // get ownership of current owner asyncParseClientID(zk, lockPath, children.get(0)) .whenComplete(new FutureEventListener<Pair<String, Long>>() { @Override public void onSuccess(Pair<String, Long> currentOwner) { watchLockOwner(lockWatcher, wait, cid, children.get(memberIndex - 1), children.get(0), currentOwner, promise); } @Override public void onFailure(final Throwable cause) { // ensure promise is satisfied in lock thread executeLockAction(lockWatcher.epoch, new LockAction() { @Override public void execute() { promise.completeExceptionally(cause); } @Override public String getActionName() { return "handleFailureOnParseClientID(lockPath=" + lockPath + ")"; } }, promise); } }); } else { LOG.error("Member {} doesn't exist in the members list {} for lock {}.", new Object[] { cid, children, lockPath }); promise.completeExceptionally(new UnexpectedException("Member " + cid + " doesn't exist in member list " + children + " for lock " + lockPath)); } } @Override public String getActionName() { return "processLockWaiters(rc=" + getChildrenRc + ", waiters=" + children + ")"; } }, promise); }
From source file:org.apache.distributedlog.lock.ZKSessionLock.java
/** * Check Lock Owner Phase 3: watch sibling node for lock ownership. * * @param lockWatcher//from w w w. ja va2 s.c o m * lock watcher. * @param wait * whether to wait for ownership. * @param myNode * my lock node. * @param siblingNode * my sibling lock node. * @param ownerNode * owner lock node. * @param currentOwner * current owner info. * @param promise * promise to satisfy with current lock owner. */ private void watchLockOwner(final LockWatcher lockWatcher, final boolean wait, final String myNode, final String siblingNode, final String ownerNode, final Pair<String, Long> currentOwner, final CompletableFuture<String> promise) { executeLockAction(lockWatcher.epoch, new LockAction() { @Override public void execute() { boolean shouldWatch; final boolean shouldClaimOwnership; if (lockContext.hasLockId(currentOwner) && siblingNode.equals(ownerNode)) { // if the current owner is the znode left from previous session // we should watch it and claim ownership shouldWatch = true; shouldClaimOwnership = true; LOG.info( "LockWatcher {} for {} found its previous session {} held lock," + " watch it to claim ownership.", new Object[] { myNode, lockPath, currentOwner }); } else if (lockId.compareTo(currentOwner) == 0 && areLockWaitersInSameSession(siblingNode, ownerNode)) { // I found that my sibling is the current owner with same lock id (client id & session id) // It must be left by any race condition from same zookeeper client shouldWatch = true; shouldClaimOwnership = true; LOG.info( "LockWatcher {} for {} found itself {} already held lock at sibling node {}," + " watch it to claim ownership.", new Object[] { myNode, lockPath, lockId, siblingNode }); } else { shouldWatch = wait; if (wait) { if (LOG.isDebugEnabled()) { LOG.debug( "Current LockWatcher for {} with ephemeral node {}, " + "is waiting for {} to release lock at {}.", new Object[] { lockPath, myNode, siblingNode, System.currentTimeMillis() }); } } shouldClaimOwnership = false; } // watch sibling for lock ownership if (shouldWatch) { watchedNode = String.format("%s/%s", lockPath, siblingNode); zk.exists(watchedNode, lockWatcher, new AsyncCallback.StatCallback() { @Override public void processResult(final int rc, String path, Object ctx, final Stat stat) { executeLockAction(lockWatcher.epoch, new LockAction() { @Override public void execute() { if (!lockState.inState(State.PREPARED)) { promise.completeExceptionally(new LockStateChangedException(lockPath, lockId, State.PREPARED, lockState.getState())); return; } if (KeeperException.Code.OK.intValue() == rc) { if (shouldClaimOwnership) { // watch owner successfully LOG.info( "LockWatcher {} claimed ownership for {} after set watcher on {}.", new Object[] { myNode, lockPath, ownerNode }); claimOwnership(lockWatcher.epoch); promise.complete(currentOwner.getLeft()); } else { // watch sibling successfully lockState.transition(State.WAITING); promise.complete(currentOwner.getLeft()); } } else if (KeeperException.Code.NONODE.intValue() == rc) { // sibling just disappeared, it might be the chance to claim ownership checkLockOwnerAndWaitIfPossible(lockWatcher, wait, promise); } else { promise.completeExceptionally( KeeperException.create(KeeperException.Code.get(rc))); } } @Override public String getActionName() { StringBuilder sb = new StringBuilder(); sb.append("postWatchLockOwner(myNode=").append(myNode).append(", siblingNode=") .append(siblingNode).append(", ownerNode=").append(ownerNode) .append(")"); return sb.toString(); } }, promise); } }, null); } else { promise.complete(currentOwner.getLeft()); } } @Override public String getActionName() { StringBuilder sb = new StringBuilder(); sb.append("watchLockOwner(myNode=").append(myNode).append(", siblingNode=").append(siblingNode) .append(", ownerNode=").append(ownerNode).append(")"); return sb.toString(); } }, promise); }
From source file:org.apache.hadoop.hbase.AsyncMetaTableAccessor.java
public static CompletableFuture<Optional<TableState>> getTableState(RawAsyncTable metaTable, TableName tableName) {/*from w w w. jav a 2 s . c o m*/ CompletableFuture<Optional<TableState>> future = new CompletableFuture<>(); Get get = new Get(tableName.getName()).addColumn(getTableFamily(), getStateColumn()); long time = EnvironmentEdgeManager.currentTime(); try { get.setTimeRange(0, time); metaTable.get(get).whenComplete((result, error) -> { if (error != null) { future.completeExceptionally(error); return; } try { future.complete(getTableState(result)); } catch (IOException e) { future.completeExceptionally(e); } }); } catch (IOException ioe) { future.completeExceptionally(ioe); } return future; }