List of usage examples for com.google.common.util.concurrent SettableFuture addListener
@Override public void addListener(Runnable runnable, Executor executor)
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(); }