Example usage for java.util.concurrent CompletableFuture completeExceptionally

List of usage examples for java.util.concurrent CompletableFuture completeExceptionally

Introduction

In this page you can find the example usage for java.util.concurrent CompletableFuture completeExceptionally.

Prototype

public boolean completeExceptionally(Throwable ex) 

Source Link

Document

If not already completed, causes invocations of #get() and related methods to throw the given exception.

Usage

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;
}