Example usage for com.google.common.util.concurrent SettableFuture addListener

List of usage examples for com.google.common.util.concurrent SettableFuture addListener

Introduction

In this page you can find the example usage for com.google.common.util.concurrent SettableFuture addListener.

Prototype

@Override
    public void addListener(Runnable runnable, Executor executor) 

Source Link

Usage

From source file:com.yahoo.yqlplus.engine.internal.scope.ScopedTracingExecutor.java

public <T> ListenableFuture<T> withTimeout(final ListenableFuture<T> source, long timeout,
        TimeUnit timeoutUnits) {/*from www  .  j a v  a 2 s .com*/
    if (timeout != 0) {
        final SettableFuture<T> result = SettableFuture.create();
        final Future<?> scheduledFuture = timers
                .schedule(new TimeoutTask<T>(source, result, timeout, timeoutUnits), timeout, timeoutUnits);
        result.addListener(new Runnable() {
            @Override
            public void run() {
                scheduledFuture.cancel(false);
                if (result.isCancelled()) {
                    source.cancel(true);
                }
            }
        }, MoreExecutors.sameThreadExecutor());
        Futures.addCallback(source, new FutureCallback<T>() {
            @Override
            public void onSuccess(T out) {
                scheduledFuture.cancel(false);
                result.set(out);
            }

            @Override
            public void onFailure(Throwable t) {
                scheduledFuture.cancel(false);
                result.setException(t);
            }
        });
        return new WrappedListenableFuture<>(result);
    } else {
        return new WrappedListenableFuture<>(source);
    }
}

From source file:com.facebook.presto.execution.ClusterSizeMonitor.java

public synchronized ListenableFuture<?> waitForMinimumWorkers() {
    if (currentCount >= executionMinCount) {
        return immediateFuture(null);
    }/*from   ww w .  j ava  2 s.co  m*/

    SettableFuture<?> future = SettableFuture.create();
    futures.add(future);

    // if future does not finish in wait period, complete with an exception
    ScheduledFuture<?> timeoutTask = executor.schedule(() -> {
        synchronized (this) {
            future.setException(new PrestoException(GENERIC_INSUFFICIENT_RESOURCES, format(
                    "Insufficient active worker nodes. Waited %s for at least %s workers, but only %s workers are active",
                    executionMaxWait, executionMinCount, currentCount)));
        }
    }, executionMaxWait.toMillis(), MILLISECONDS);

    // remove future if finished (e.g., canceled, timed out)
    future.addListener(() -> {
        timeoutTask.cancel(true);
        removeFuture(future);
    }, executor);

    return future;
}

From source file:io.prestosql.execution.ClusterSizeMonitor.java

/**
 * Returns a listener that completes when the minimum number of workers for the cluster has been met.
 * Note: caller should not add a listener using the direct executor, as this can delay the
 * notifications for other listeners.//from ww  w  .j  a  va2 s .c o m
 */
public synchronized ListenableFuture<?> waitForMinimumWorkers() {
    if (currentCount >= executionMinCount) {
        return immediateFuture(null);
    }

    SettableFuture<?> future = SettableFuture.create();
    futures.add(future);

    // if future does not finish in wait period, complete with an exception
    ScheduledFuture<?> timeoutTask = executor.schedule(() -> {
        synchronized (this) {
            future.setException(new PrestoException(GENERIC_INSUFFICIENT_RESOURCES, format(
                    "Insufficient active worker nodes. Waited %s for at least %s workers, but only %s workers are active",
                    executionMaxWait, executionMinCount, currentCount)));
        }
    }, executionMaxWait.toMillis(), MILLISECONDS);

    // remove future if finished (e.g., canceled, timed out)
    future.addListener(() -> {
        timeoutTask.cancel(true);
        removeFuture(future);
    }, executor);

    return future;
}

From source file:org.apache.twill.internal.zookeeper.ReentrantDistributedLock.java

/**
 * Acquires a distributed lock through ZooKeeper.
 *
 * @param interruptible true if acquisition of lock can be interrupted
 * @param waitForLock true if wants to wait for the lock when not able to acquire it
 * @param timeout time to wait for the lock before giving up
 * @param unit unit for the timeout//  w  w  w.  jav a  2  s  .co m
 * @throws InterruptedException if {@code interruptible} is set to {@code true} and the current thread is interrupted
 *                              while acquiring the lock
 * @throws ExecutionException if there is failure while trying to acquire the lock
 */
private boolean acquire(boolean interruptible, final boolean waitForLock, long timeout, TimeUnit unit)
        throws InterruptedException, ExecutionException, TimeoutException {
    Preconditions.checkState(lock.isHeldByCurrentThread(), "Not owner of local lock.");
    if (lock.getHoldCount() > 1) {
        // Already owner of the lock, simply return.
        return true;
    }

    // Use a Future to help deal with different variants of locking
    // (lock, lockInterruptibly, tryLock, tryLock with timeout)
    // When the completion future is completed successfully, it means the lock is acquired and the future contains
    // the ZK node path to the ephemeral node that is representing this lock.
    // If it is failed, it means there is exception while trying to acquire the lock
    // If it is cancelled, it means to abort the acquisition logic (due to timeout / interrupt).
    final SettableFuture<String> completion = SettableFuture.create();

    // If the connection expired, fail the locking process if it is still in progress
    final Cancellable watcherCancellable = zkClient.addConnectionWatcher(new Watcher() {
        @Override
        public void process(WatchedEvent event) {
            if (event.getState() == Event.KeeperState.Expired) {
                completion.setException(new IllegalStateException("ZK session expired"));
            }
        }
    });
    // Always remove the watcher on completion
    completion.addListener(new Runnable() {
        @Override
        public void run() {
            watcherCancellable.cancel();
        }
    }, Threads.SAME_THREAD_EXECUTOR);

    // Step 1. Create a ephemeral sequential node
    final String guid = UUID.randomUUID().toString();
    final String lockPath = String.format("%s/%s-", path, guid);
    OperationFuture<String> future = zkClient.create(lockPath, null, CreateMode.EPHEMERAL_SEQUENTIAL, true);

    Futures.addCallback(future, new FutureCallback<String>() {
        @Override
        public void onSuccess(final String lockNode) {
            // If lock failed due to whatever reason, delete the lock node.
            deleteNodeOnFailure(completion, lockNode);

            // If the lock is completed (mainly due to cancellation), simply abort the lock acquisition logic.
            if (completion.isDone()) {
                return;
            }

            // Step 2-5. Try to determine who is the lock owner and watch for ZK node changes if itself is not the owner.
            doAcquire(completion, waitForLock, guid, lockNode);
        }

        @Override
        public void onFailure(Throwable t) {
            if (t instanceof KeeperException.ConnectionLossException) {
                // Ignore connection exception in create. Going to handle it in next step.
                // See the ZK receipt for details about the possible failure situation that can cause this.
                doAcquire(completion, waitForLock, guid, null);
            } else {
                LOG.error("Exception raised when creating lock node at {}", lockPath, t);
                completion.setException(t);
            }
        }
    });

    // Gets the result from the completion
    try {
        if (interruptible) {
            localLockNode.set(completion.get(timeout, unit));
        } else {
            localLockNode.set(Uninterruptibles.getUninterruptibly(completion, timeout, unit));
        }
        return true;
    } catch (InterruptedException e) {
        completion.cancel(true);
        throw e;
    } catch (TimeoutException e) {
        completion.cancel(true);
        throw e;
    } catch (CancellationException e) {
        // If the completion get cancelled, meaning the lock acquisition is aborted.
        return false;
    }
}

From source file:org.usrz.libs.utils.concurrent.SimpleExecutor.java

public <T> NotifyingFuture<T> call(Callable<T> callable) {
    final SettableFuture<T> settableFuture = SettableFuture.create();

    final Future<T> executingFuture = executor.submit(() -> {
        try {/*from  ww  w. j  a  va 2 s  .  c o  m*/
            final T result = callable.call();
            settableFuture.set(result);
            return result;
        } catch (Throwable throwable) {
            settableFuture.setException(throwable);
            throw new Exception(throwable);
        }
    });

    return new NotifyingFuture<T>() {

        @Override
        public boolean cancel(boolean mayInterruptIfRunning) {
            if (executingFuture.cancel(mayInterruptIfRunning)) {
                settableFuture.cancel(mayInterruptIfRunning);
                return true;
            } else {
                return false;
            }
        }

        @Override
        public boolean isCancelled() {
            return settableFuture.isCancelled();
        }

        @Override
        public boolean isDone() {
            return settableFuture.isCancelled();
        }

        @Override
        public T get() throws InterruptedException, ExecutionException {
            return settableFuture.get();
        }

        @Override
        public T get(long timeout, TimeUnit unit)
                throws InterruptedException, ExecutionException, TimeoutException {
            return settableFuture.get(timeout, unit);
        }

        @Override
        public NotifyingFuture<T> withConsumer(Consumer<Future<T>> consumer) {
            settableFuture.addListener(() -> consumer.accept(settableFuture), notifier);
            return this;
        }

    };
}

From source file:com.google.devtools.build.lib.remote.ByteStreamUploader.java

private void startAsyncUploadWithRetry(Chunker chunker, Retrier.Backoff backoffTimes,
        SettableFuture<Void> overallUploadResult) {

    AsyncUpload.Listener listener = new AsyncUpload.Listener() {
        @Override//from  www.  j  av  a2 s .c  o  m
        public void success() {
            overallUploadResult.set(null);
        }

        @Override
        public void failure(Status status) {
            StatusException cause = status.asException();
            long nextDelayMillis = backoffTimes.nextDelayMillis();
            if (nextDelayMillis < 0 || !retrier.isRetriable(status)) {
                // Out of retries or status not retriable.
                RetryException error = new RetryException(cause, backoffTimes.getRetryAttempts());
                overallUploadResult.setException(error);
            } else {
                retryAsyncUpload(nextDelayMillis, chunker, backoffTimes, overallUploadResult);
            }
        }

        private void retryAsyncUpload(long nextDelayMillis, Chunker chunker, Retrier.Backoff backoffTimes,
                SettableFuture<Void> overallUploadResult) {
            try {
                ListenableScheduledFuture<?> schedulingResult = retryService.schedule(
                        Context.current().wrap(
                                () -> startAsyncUploadWithRetry(chunker, backoffTimes, overallUploadResult)),
                        nextDelayMillis, MILLISECONDS);
                // In case the scheduled execution errors, we need to notify the overallUploadResult.
                schedulingResult.addListener(() -> {
                    try {
                        schedulingResult.get();
                    } catch (Exception e) {
                        overallUploadResult
                                .setException(new RetryException(e, backoffTimes.getRetryAttempts()));
                    }
                }, MoreExecutors.directExecutor());
            } catch (RejectedExecutionException e) {
                // May be thrown by .schedule(...) if i.e. the executor is shutdown.
                overallUploadResult.setException(new RetryException(e, backoffTimes.getRetryAttempts()));
            }
        }
    };

    try {
        chunker.reset();
    } catch (IOException e) {
        overallUploadResult.setException(e);
        return;
    }

    AsyncUpload newUpload = new AsyncUpload(channel, callCredentials, callTimeoutSecs, instanceName, chunker,
            listener);
    overallUploadResult.addListener(() -> {
        if (overallUploadResult.isCancelled()) {
            newUpload.cancel();
        }
    }, MoreExecutors.directExecutor());
    newUpload.start();
}