/* * Copyright (C) 2006 The Guava Authors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.google.common.util.concurrent; import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkState; import static com.google.common.util.concurrent.MoreExecutors.directExecutor; import static com.google.common.util.concurrent.Uninterruptibles.getUninterruptibly; import static java.lang.Thread.currentThread; import static java.util.Arrays.asList; import com.google.common.annotations.Beta; import com.google.common.base.Function; import com.google.common.base.Optional; import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableCollection; import com.google.common.collect.ImmutableList; import com.google.common.collect.Lists; import com.google.common.collect.Ordering; import com.google.common.collect.Queues; import com.google.common.collect.Sets; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.UndeclaredThrowableException; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Set; import java.util.concurrent.Callable; import java.util.concurrent.CancellationException; import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.ExecutionException; import java.util.concurrent.Executor; import java.util.concurrent.Future; import java.util.concurrent.RejectedExecutionException; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; import java.util.logging.Level; import java.util.logging.Logger; import javax.annotation.Nullable; /** * Static utility methods pertaining to the {@link Future} interface. * * <p>Many of these methods use the {@link ListenableFuture} API; consult the * Guava User Guide article on <a href= * "http://code.google.com/p/guava-libraries/wiki/ListenableFutureExplained"> * {@code ListenableFuture}</a>. * * @author Kevin Bourrillion * @author Nishant Thakkar * @author Sven Mawson * @since 1.0 */ @Beta public final class Futures { private Futures() {} /** * Creates a {@link CheckedFuture} out of a normal {@link ListenableFuture} * and a {@link Function} that maps from {@link Exception} instances into the * appropriate checked type. * * <p>The given mapping function will be applied to an * {@link InterruptedException}, a {@link CancellationException}, or an * {@link ExecutionException}. * See {@link Future#get()} for details on the exceptions thrown. * * @since 9.0 (source-compatible since 1.0) */ public static <V, X extends Exception> CheckedFuture<V, X> makeChecked( ListenableFuture<V> future, Function<? super Exception, X> mapper) { return new MappingCheckedFuture<V, X>(checkNotNull(future), mapper); } private abstract static class ImmediateFuture<V> implements ListenableFuture<V> { private static final Logger log = Logger.getLogger(ImmediateFuture.class.getName()); @Override public void addListener(Runnable listener, Executor executor) { checkNotNull(listener, "Runnable was null."); checkNotNull(executor, "Executor was null."); try { executor.execute(listener); } catch (RuntimeException e) { // ListenableFuture's contract is that it will not throw unchecked // exceptions, so log the bad runnable and/or executor and swallow it. log.log(Level.SEVERE, "RuntimeException while executing runnable " + listener + " with executor " + executor, e); } } @Override public boolean cancel(boolean mayInterruptIfRunning) { return false; } @Override public abstract V get() throws ExecutionException; @Override public V get(long timeout, TimeUnit unit) throws ExecutionException { checkNotNull(unit); return get(); } @Override public boolean isCancelled() { return false; } @Override public boolean isDone() { return true; } } private static class ImmediateSuccessfulFuture<V> extends ImmediateFuture<V> { @Nullable private final V value; ImmediateSuccessfulFuture(@Nullable V value) { this.value = value; } @Override public V get() { return value; } } private static class ImmediateSuccessfulCheckedFuture<V, X extends Exception> extends ImmediateFuture<V> implements CheckedFuture<V, X> { @Nullable private final V value; ImmediateSuccessfulCheckedFuture(@Nullable V value) { this.value = value; } @Override public V get() { return value; } @Override public V checkedGet() { return value; } @Override public V checkedGet(long timeout, TimeUnit unit) { checkNotNull(unit); return value; } } private static class ImmediateFailedFuture<V> extends ImmediateFuture<V> { private final Throwable thrown; ImmediateFailedFuture(Throwable thrown) { this.thrown = thrown; } @Override public V get() throws ExecutionException { throw new ExecutionException(thrown); } } private static class ImmediateCancelledFuture<V> extends ImmediateFuture<V> { private final CancellationException thrown; ImmediateCancelledFuture() { this.thrown = new CancellationException("Immediate cancelled future."); } @Override public boolean isCancelled() { return true; } @Override public V get() { throw AbstractFuture.cancellationExceptionWithCause( "Task was cancelled.", thrown); } } private static class ImmediateFailedCheckedFuture<V, X extends Exception> extends ImmediateFuture<V> implements CheckedFuture<V, X> { private final X thrown; ImmediateFailedCheckedFuture(X thrown) { this.thrown = thrown; } @Override public V get() throws ExecutionException { throw new ExecutionException(thrown); } @Override public V checkedGet() throws X { throw thrown; } @Override public V checkedGet(long timeout, TimeUnit unit) throws X { checkNotNull(unit); throw thrown; } } /** * Creates a {@code ListenableFuture} which has its value set immediately upon * construction. The getters just return the value. This {@code Future} can't * be canceled or timed out and its {@code isDone()} method always returns * {@code true}. */ public static <V> ListenableFuture<V> immediateFuture(@Nullable V value) { return new ImmediateSuccessfulFuture<V>(value); } /** * Returns a {@code CheckedFuture} which has its value set immediately upon * construction. * * <p>The returned {@code Future} can't be cancelled, and its {@code isDone()} * method always returns {@code true}. Calling {@code get()} or {@code * checkedGet()} will immediately return the provided value. */ public static <V, X extends Exception> CheckedFuture<V, X> immediateCheckedFuture(@Nullable V value) { return new ImmediateSuccessfulCheckedFuture<V, X>(value); } /** * Returns a {@code ListenableFuture} which has an exception set immediately * upon construction. * * <p>The returned {@code Future} can't be cancelled, and its {@code isDone()} * method always returns {@code true}. Calling {@code get()} will immediately * throw the provided {@code Throwable} wrapped in an {@code * ExecutionException}. */ public static <V> ListenableFuture<V> immediateFailedFuture( Throwable throwable) { checkNotNull(throwable); return new ImmediateFailedFuture<V>(throwable); } /** * Creates a {@code ListenableFuture} which is cancelled immediately upon * construction, so that {@code isCancelled()} always returns {@code true}. * * @since 14.0 */ public static <V> ListenableFuture<V> immediateCancelledFuture() { return new ImmediateCancelledFuture<V>(); } /** * Returns a {@code CheckedFuture} which has an exception set immediately upon * construction. * * <p>The returned {@code Future} can't be cancelled, and its {@code isDone()} * method always returns {@code true}. Calling {@code get()} will immediately * throw the provided {@code Exception} wrapped in an {@code * ExecutionException}, and calling {@code checkedGet()} will throw the * provided exception itself. */ public static <V, X extends Exception> CheckedFuture<V, X> immediateFailedCheckedFuture(X exception) { checkNotNull(exception); return new ImmediateFailedCheckedFuture<V, X>(exception); } /** * Returns a {@code Future} whose result is taken from the given primary * {@code input} or, if the primary input fails, from the {@code Future} * provided by the {@code fallback}. {@link FutureFallback#create} is not * invoked until the primary input has failed, so if the primary input * succeeds, it is never invoked. If, during the invocation of {@code * fallback}, an exception is thrown, this exception is used as the result of * the output {@code Future}. * * <p>Below is an example of a fallback that returns a default value if an * exception occurs: * * <pre> {@code * ListenableFuture<Integer> fetchCounterFuture = ...; * * // Falling back to a zero counter in case an exception happens when * // processing the RPC to fetch counters. * ListenableFuture<Integer> faultTolerantFuture = Futures.withFallback( * fetchCounterFuture, new FutureFallback<Integer>() { * public ListenableFuture<Integer> create(Throwable t) { * // Returning "0" as the default for the counter when the * // exception happens. * return immediateFuture(0); * } * });}</pre> * * <p>The fallback can also choose to propagate the original exception when * desired: * * <pre> {@code * ListenableFuture<Integer> fetchCounterFuture = ...; * * // Falling back to a zero counter only in case the exception was a * // TimeoutException. * ListenableFuture<Integer> faultTolerantFuture = Futures.withFallback( * fetchCounterFuture, new FutureFallback<Integer>() { * public ListenableFuture<Integer> create(Throwable t) { * if (t instanceof TimeoutException) { * return immediateFuture(0); * } * return immediateFailedFuture(t); * } * });}</pre> * * <p>Note: If the derived {@code Future} is slow or heavyweight to create * (whether the {@code Future} itself is slow or heavyweight to complete is * irrelevant), consider {@linkplain #withFallback(ListenableFuture, * FutureFallback, Executor) supplying an executor}. If you do not supply an * executor, {@code withFallback} will use a * {@linkplain MoreExecutors#directExecutor direct executor}, which carries * some caveats for heavier operations. For example, the call to {@code * fallback.create} may run on an unpredictable or undesirable thread: * * <ul> * <li>If the input {@code Future} is done at the time {@code withFallback} * is called, {@code withFallback} will call {@code fallback.create} inline. * <li>If the input {@code Future} is not yet done, {@code withFallback} will * schedule {@code fallback.create} to be run by the thread that completes * the input {@code Future}, which may be an internal system thread such as * an RPC network thread. * </ul> * * <p>Also note that, regardless of which thread executes the {@code * fallback.create}, all other registered but unexecuted listeners are * prevented from running during its execution, even if those listeners are * to run in other executors. * * @param input the primary input {@code Future} * @param fallback the {@link FutureFallback} implementation to be called if * {@code input} fails * @since 14.0 */ public static <V> ListenableFuture<V> withFallback( ListenableFuture<? extends V> input, FutureFallback<? extends V> fallback) { return withFallback(input, fallback, directExecutor()); } /** * Returns a {@code Future} whose result is taken from the given primary * {@code input} or, if the primary input fails, from the {@code Future} * provided by the {@code fallback}. {@link FutureFallback#create} is not * invoked until the primary input has failed, so if the primary input * succeeds, it is never invoked. If, during the invocation of {@code * fallback}, an exception is thrown, this exception is used as the result of * the output {@code Future}. * * <p>Below is an example of a fallback that returns a default value if an * exception occurs: * * <pre> {@code * ListenableFuture<Integer> fetchCounterFuture = ...; * * // Falling back to a zero counter in case an exception happens when * // processing the RPC to fetch counters. * ListenableFuture<Integer> faultTolerantFuture = Futures.withFallback( * fetchCounterFuture, new FutureFallback<Integer>() { * public ListenableFuture<Integer> create(Throwable t) { * // Returning "0" as the default for the counter when the * // exception happens. * return immediateFuture(0); * } * }, directExecutor());}</pre> * * <p>The fallback can also choose to propagate the original exception when * desired: * * <pre> {@code * ListenableFuture<Integer> fetchCounterFuture = ...; * * // Falling back to a zero counter only in case the exception was a * // TimeoutException. * ListenableFuture<Integer> faultTolerantFuture = Futures.withFallback( * fetchCounterFuture, new FutureFallback<Integer>() { * public ListenableFuture<Integer> create(Throwable t) { * if (t instanceof TimeoutException) { * return immediateFuture(0); * } * return immediateFailedFuture(t); * } * }, directExecutor());}</pre> * * <p>When the execution of {@code fallback.create} is fast and lightweight * (though the {@code Future} it returns need not meet these criteria), * consider {@linkplain #withFallback(ListenableFuture, FutureFallback) * omitting the executor} or explicitly specifying {@code * directExecutor}. However, be aware of the caveats documented in the * link above. * * @param input the primary input {@code Future} * @param fallback the {@link FutureFallback} implementation to be called if * {@code input} fails * @param executor the executor that runs {@code fallback} if {@code input} * fails * @since 14.0 */ public static <V> ListenableFuture<V> withFallback( ListenableFuture<? extends V> input, FutureFallback<? extends V> fallback, Executor executor) { checkNotNull(fallback); return new FallbackFuture<V>(input, fallback, executor); } /** * A future that falls back on a second, generated future, in case its * original future fails. */ private static class FallbackFuture<V> extends AbstractFuture<V> { private volatile ListenableFuture<? extends V> running; FallbackFuture(ListenableFuture<? extends V> input, final FutureFallback<? extends V> fallback, final Executor executor) { running = input; addCallback(running, new FutureCallback<V>() { @Override public void onSuccess(V value) { set(value); } @Override public void onFailure(Throwable t) { if (isCancelled()) { return; } try { running = fallback.create(t); if (isCancelled()) { // in case cancel called in the meantime running.cancel(wasInterrupted()); return; } addCallback(running, new FutureCallback<V>() { @Override public void onSuccess(V value) { set(value); } @Override public void onFailure(Throwable t) { if (running.isCancelled()) { cancel(false); } else { setException(t); } } }, directExecutor()); } catch (Throwable e) { setException(e); } } }, executor); } @Override public boolean cancel(boolean mayInterruptIfRunning) { if (super.cancel(mayInterruptIfRunning)) { running.cancel(mayInterruptIfRunning); return true; } return false; } } /** * Returns a new {@code ListenableFuture} whose result is asynchronously * derived from the result of the given {@code Future}. More precisely, the * returned {@code Future} takes its result from a {@code Future} produced by * applying the given {@code AsyncFunction} to the result of the original * {@code Future}. Example: * * <pre> {@code * ListenableFuture<RowKey> rowKeyFuture = indexService.lookUp(query); * AsyncFunction<RowKey, QueryResult> queryFunction = * new AsyncFunction<RowKey, QueryResult>() { * public ListenableFuture<QueryResult> apply(RowKey rowKey) { * return dataService.read(rowKey); * } * }; * ListenableFuture<QueryResult> queryFuture = * transform(rowKeyFuture, queryFunction);}</pre> * * <p>Note: If the derived {@code Future} is slow or heavyweight to create * (whether the {@code Future} itself is slow or heavyweight to complete is * irrelevant), consider {@linkplain #transform(ListenableFuture, * AsyncFunction, Executor) supplying an executor}. If you do not supply an * executor, {@code transform} will use a * {@linkplain MoreExecutors#directExecutor direct executor}, which carries * some caveats for heavier operations. For example, the call to {@code * function.apply} may run on an unpredictable or undesirable thread: * * <ul> * <li>If the input {@code Future} is done at the time {@code transform} is * called, {@code transform} will call {@code function.apply} inline. * <li>If the input {@code Future} is not yet done, {@code transform} will * schedule {@code function.apply} to be run by the thread that completes the * input {@code Future}, which may be an internal system thread such as an * RPC network thread. * </ul> * * <p>Also note that, regardless of which thread executes the {@code * function.apply}, all other registered but unexecuted listeners are * prevented from running during its execution, even if those listeners are * to run in other executors. * * <p>The returned {@code Future} attempts to keep its cancellation state in * sync with that of the input future and that of the future returned by the * function. That is, if the returned {@code Future} is cancelled, it will * attempt to cancel the other two, and if either of the other two is * cancelled, the returned {@code Future} will receive a callback in which it * will attempt to cancel itself. * * @param input The future to transform * @param function A function to transform the result of the input future * to the result of the output future * @return A future that holds result of the function (if the input succeeded) * or the original input's failure (if not) * @since 11.0 */ public static <I, O> ListenableFuture<O> transform(ListenableFuture<I> input, AsyncFunction<? super I, ? extends O> function) { ChainingListenableFuture<I, O> output = new ChainingListenableFuture<I, O>(function, input); input.addListener(output, directExecutor()); return output; } /** * Returns a new {@code ListenableFuture} whose result is asynchronously * derived from the result of the given {@code Future}. More precisely, the * returned {@code Future} takes its result from a {@code Future} produced by * applying the given {@code AsyncFunction} to the result of the original * {@code Future}. Example: * * <pre> {@code * ListenableFuture<RowKey> rowKeyFuture = indexService.lookUp(query); * AsyncFunction<RowKey, QueryResult> queryFunction = * new AsyncFunction<RowKey, QueryResult>() { * public ListenableFuture<QueryResult> apply(RowKey rowKey) { * return dataService.read(rowKey); * } * }; * ListenableFuture<QueryResult> queryFuture = * transform(rowKeyFuture, queryFunction, executor);}</pre> * * <p>The returned {@code Future} attempts to keep its cancellation state in * sync with that of the input future and that of the future returned by the * chain function. That is, if the returned {@code Future} is cancelled, it * will attempt to cancel the other two, and if either of the other two is * cancelled, the returned {@code Future} will receive a callback in which it * will attempt to cancel itself. * * <p>When the execution of {@code function.apply} is fast and lightweight * (though the {@code Future} it returns need not meet these criteria), * consider {@linkplain #transform(ListenableFuture, AsyncFunction) omitting * the executor} or explicitly specifying {@code directExecutor}. * However, be aware of the caveats documented in the link above. * * @param input The future to transform * @param function A function to transform the result of the input future * to the result of the output future * @param executor Executor to run the function in. * @return A future that holds result of the function (if the input succeeded) * or the original input's failure (if not) * @since 11.0 */ public static <I, O> ListenableFuture<O> transform(ListenableFuture<I> input, AsyncFunction<? super I, ? extends O> function, Executor executor) { checkNotNull(executor); ChainingListenableFuture<I, O> output = new ChainingListenableFuture<I, O>(function, input); input.addListener(rejectionPropagatingRunnable(output, output, executor), directExecutor()); return output; } /** * Returns a Runnable that will invoke the delegate Runnable on the delegate executor, but if the * task is rejected, it will propagate that rejection to the output future. */ private static Runnable rejectionPropagatingRunnable( final AbstractFuture<?> outputFuture, final Runnable delegateTask, final Executor delegateExecutor) { return new Runnable() { @Override public void run() { final AtomicBoolean thrownFromDelegate = new AtomicBoolean(true); try { delegateExecutor.execute(new Runnable() { @Override public void run() { thrownFromDelegate.set(false); delegateTask.run(); } }); } catch (RejectedExecutionException e) { if (thrownFromDelegate.get()) { // wrap exception? outputFuture.setException(e); } // otherwise it must have been thrown from a transitive call and the delegate runnable // should have handled it. } } }; } /** * Returns a new {@code ListenableFuture} whose result is the product of * applying the given {@code Function} to the result of the given {@code * Future}. Example: * * <pre> {@code * ListenableFuture<QueryResult> queryFuture = ...; * Function<QueryResult, List<Row>> rowsFunction = * new Function<QueryResult, List<Row>>() { * public List<Row> apply(QueryResult queryResult) { * return queryResult.getRows(); * } * }; * ListenableFuture<List<Row>> rowsFuture = * transform(queryFuture, rowsFunction);}</pre> * * <p>Note: If the transformation is slow or heavyweight, consider {@linkplain * #transform(ListenableFuture, Function, Executor) supplying an executor}. * If you do not supply an executor, {@code transform} will use an inline * executor, which carries some caveats for heavier operations. For example, * the call to {@code function.apply} may run on an unpredictable or * undesirable thread: * * <ul> * <li>If the input {@code Future} is done at the time {@code transform} is * called, {@code transform} will call {@code function.apply} inline. * <li>If the input {@code Future} is not yet done, {@code transform} will * schedule {@code function.apply} to be run by the thread that completes the * input {@code Future}, which may be an internal system thread such as an * RPC network thread. * </ul> * * <p>Also note that, regardless of which thread executes the {@code * function.apply}, all other registered but unexecuted listeners are * prevented from running during its execution, even if those listeners are * to run in other executors. * * <p>The returned {@code Future} attempts to keep its cancellation state in * sync with that of the input future. That is, if the returned {@code Future} * is cancelled, it will attempt to cancel the input, and if the input is * cancelled, the returned {@code Future} will receive a callback in which it * will attempt to cancel itself. * * <p>An example use of this method is to convert a serializable object * returned from an RPC into a POJO. * * @param input The future to transform * @param function A Function to transform the results of the provided future * to the results of the returned future. This will be run in the thread * that notifies input it is complete. * @return A future that holds result of the transformation. * @since 9.0 (in 1.0 as {@code compose}) */ public static <I, O> ListenableFuture<O> transform(ListenableFuture<I> input, final Function<? super I, ? extends O> function) { checkNotNull(function); ChainingListenableFuture<I, O> output = new ChainingListenableFuture<I, O>(asAsyncFunction(function), input); input.addListener(output, directExecutor()); return output; } /** * Returns a new {@code ListenableFuture} whose result is the product of * applying the given {@code Function} to the result of the given {@code * Future}. Example: * * <pre> {@code * ListenableFuture<QueryResult> queryFuture = ...; * Function<QueryResult, List<Row>> rowsFunction = * new Function<QueryResult, List<Row>>() { * public List<Row> apply(QueryResult queryResult) { * return queryResult.getRows(); * } * }; * ListenableFuture<List<Row>> rowsFuture = * transform(queryFuture, rowsFunction, executor);}</pre> * * <p>The returned {@code Future} attempts to keep its cancellation state in * sync with that of the input future. That is, if the returned {@code Future} * is cancelled, it will attempt to cancel the input, and if the input is * cancelled, the returned {@code Future} will receive a callback in which it * will attempt to cancel itself. * * <p>An example use of this method is to convert a serializable object * returned from an RPC into a POJO. * * <p>When the transformation is fast and lightweight, consider {@linkplain * #transform(ListenableFuture, Function) omitting the executor} or * explicitly specifying {@code directExecutor}. However, be aware of the * caveats documented in the link above. * * @param input The future to transform * @param function A Function to transform the results of the provided future * to the results of the returned future. * @param executor Executor to run the function in. * @return A future that holds result of the transformation. * @since 9.0 (in 2.0 as {@code compose}) */ public static <I, O> ListenableFuture<O> transform(ListenableFuture<I> input, final Function<? super I, ? extends O> function, Executor executor) { checkNotNull(function); return transform(input, asAsyncFunction(function), executor); } /** Wraps the given function as an AsyncFunction. */ private static <I, O> AsyncFunction<I, O> asAsyncFunction( final Function<? super I, ? extends O> function) { return new AsyncFunction<I, O>() { @Override public ListenableFuture<O> apply(I input) { O output = function.apply(input); return immediateFuture(output); } }; } /** * Like {@link #transform(ListenableFuture, Function)} except that the * transformation {@code function} is invoked on each call to * {@link Future#get() get()} on the returned future. * * <p>The returned {@code Future} reflects the input's cancellation * state directly, and any attempt to cancel the returned Future is likewise * passed through to the input Future. * * <p>Note that calls to {@linkplain Future#get(long, TimeUnit) timed get} * only apply the timeout to the execution of the underlying {@code Future}, * <em>not</em> to the execution of the transformation function. * * <p>The primary audience of this method is callers of {@code transform} * who don't have a {@code ListenableFuture} available and * do not mind repeated, lazy function evaluation. * * @param input The future to transform * @param function A Function to transform the results of the provided future * to the results of the returned future. * @return A future that returns the result of the transformation. * @since 10.0 */ public static <I, O> Future<O> lazyTransform(final Future<I> input, final Function<? super I, ? extends O> function) { checkNotNull(input); checkNotNull(function); return new Future<O>() { @Override public boolean cancel(boolean mayInterruptIfRunning) { return input.cancel(mayInterruptIfRunning); } @Override public boolean isCancelled() { return input.isCancelled(); } @Override public boolean isDone() { return input.isDone(); } @Override public O get() throws InterruptedException, ExecutionException { return applyTransformation(input.get()); } @Override public O get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException { return applyTransformation(input.get(timeout, unit)); } private O applyTransformation(I input) throws ExecutionException { try { return function.apply(input); } catch (Throwable t) { throw new ExecutionException(t); } } }; } /** * An implementation of {@code ListenableFuture} that also implements * {@code Runnable} so that it can be used to nest ListenableFutures. * Once the passed-in {@code ListenableFuture} is complete, it calls the * passed-in {@code Function} to generate the result. * * <p>For historical reasons, this class has a special case in its exception * handling: If the given {@code AsyncFunction} throws an {@code * UndeclaredThrowableException}, {@code ChainingListenableFuture} unwraps it * and uses its <i>cause</i> as the output future's exception, rather than * using the {@code UndeclaredThrowableException} itself as it would for other * exception types. The reason for this is that {@code Futures.transform} used * to require a {@code Function}, whose {@code apply} method is not allowed to * throw checked exceptions. Nowadays, {@code Futures.transform} has an * overload that accepts an {@code AsyncFunction}, whose {@code apply} method * <i>is</i> allowed to throw checked exception. Users who wish to throw * checked exceptions should use that overload instead, and <a * href="http://code.google.com/p/guava-libraries/issues/detail?id=1548">we * should remove the {@code UndeclaredThrowableException} special case</a>. */ private static class ChainingListenableFuture<I, O> extends AbstractFuture<O> implements Runnable { private AsyncFunction<? super I, ? extends O> function; private ListenableFuture<? extends I> inputFuture; private volatile ListenableFuture<? extends O> outputFuture; private ChainingListenableFuture( AsyncFunction<? super I, ? extends O> function, ListenableFuture<? extends I> inputFuture) { this.function = checkNotNull(function); this.inputFuture = checkNotNull(inputFuture); } @Override public boolean cancel(boolean mayInterruptIfRunning) { /* * Our additional cancellation work needs to occur even if * !mayInterruptIfRunning, so we can't move it into interruptTask(). */ if (super.cancel(mayInterruptIfRunning)) { // This should never block since only one thread is allowed to cancel // this Future. cancel(inputFuture, mayInterruptIfRunning); cancel(outputFuture, mayInterruptIfRunning); return true; } return false; } private void cancel(@Nullable Future<?> future, boolean mayInterruptIfRunning) { if (future != null) { future.cancel(mayInterruptIfRunning); } } @Override public void run() { try { I sourceResult; try { sourceResult = getUninterruptibly(inputFuture); } catch (CancellationException e) { // Cancel this future and return. // At this point, inputFuture is cancelled and outputFuture doesn't // exist, so the value of mayInterruptIfRunning is irrelevant. cancel(false); return; } catch (ExecutionException e) { // Set the cause of the exception as this future's exception setException(e.getCause()); return; } final ListenableFuture<? extends O> outputFuture = this.outputFuture = Preconditions.checkNotNull(function.apply(sourceResult), "AsyncFunction may not return null."); if (isCancelled()) { outputFuture.cancel(wasInterrupted()); this.outputFuture = null; return; } outputFuture.addListener(new Runnable() { @Override public void run() { try { set(getUninterruptibly(outputFuture)); } catch (CancellationException e) { // Cancel this future and return. // At this point, inputFuture and outputFuture are done, so the // value of mayInterruptIfRunning is irrelevant. cancel(false); return; } catch (ExecutionException e) { // Set the cause of the exception as this future's exception setException(e.getCause()); } finally { // Don't pin inputs beyond completion ChainingListenableFuture.this.outputFuture = null; } } }, directExecutor()); } catch (UndeclaredThrowableException e) { // Set the cause of the exception as this future's exception setException(e.getCause()); } catch (Throwable t) { // This exception is irrelevant in this thread, but useful for the // client setException(t); } finally { // Don't pin inputs beyond completion function = null; inputFuture = null; } } } /** * Returns a new {@code ListenableFuture} whose result is the product of * calling {@code get()} on the {@code Future} nested within the given {@code * Future}, effectively chaining the futures one after the other. Example: * * <pre> {@code * SettableFuture<ListenableFuture<String>> nested = SettableFuture.create(); * ListenableFuture<String> dereferenced = dereference(nested);}</pre> * * <p>This call has the same cancellation and execution semantics as {@link * #transform(ListenableFuture, AsyncFunction)}, in that the returned {@code * Future} attempts to keep its cancellation state in sync with both the * input {@code Future} and the nested {@code Future}. The transformation * is very lightweight and therefore takes place in the same thread (either * the thread that called {@code dereference}, or the thread in which the * dereferenced future completes). * * @param nested The nested future to transform. * @return A future that holds result of the inner future. * @since 13.0 */ @SuppressWarnings({"rawtypes", "unchecked"}) public static <V> ListenableFuture<V> dereference( ListenableFuture<? extends ListenableFuture<? extends V>> nested) { return Futures.transform((ListenableFuture) nested, (AsyncFunction) DEREFERENCER); } /** * Helper {@code Function} for {@link #dereference}. */ private static final AsyncFunction<ListenableFuture<Object>, Object> DEREFERENCER = new AsyncFunction<ListenableFuture<Object>, Object>() { @Override public ListenableFuture<Object> apply(ListenableFuture<Object> input) { return input; } }; /** * Creates a new {@code ListenableFuture} whose value is a list containing the * values of all its input futures, if all succeed. If any input fails, the * returned future fails immediately. * * <p>The list of results is in the same order as the input list. * * <p>Canceling this future will attempt to cancel all the component futures, * and if any of the provided futures fails or is canceled, this one is, * too. * * @param futures futures to combine * @return a future that provides a list of the results of the component * futures * @since 10.0 */ @Beta public static <V> ListenableFuture<List<V>> allAsList( ListenableFuture<? extends V>... futures) { return listFuture(ImmutableList.copyOf(futures), true, directExecutor()); } /** * Creates a new {@code ListenableFuture} whose value is a list containing the * values of all its input futures, if all succeed. If any input fails, the * returned future fails immediately. * * <p>The list of results is in the same order as the input list. * * <p>Canceling this future will attempt to cancel all the component futures, * and if any of the provided futures fails or is canceled, this one is, * too. * * @param futures futures to combine * @return a future that provides a list of the results of the component * futures * @since 10.0 */ @Beta public static <V> ListenableFuture<List<V>> allAsList( Iterable<? extends ListenableFuture<? extends V>> futures) { return listFuture(ImmutableList.copyOf(futures), true, directExecutor()); } private static final class WrappedCombiner<T> implements Callable<T> { final Callable<T> delegate; CombinerFuture<T> outputFuture; WrappedCombiner(Callable<T> delegate) { this.delegate = checkNotNull(delegate); } @Override public T call() throws Exception { try { return delegate.call(); } catch (ExecutionException e) { outputFuture.setException(e.getCause()); } catch (CancellationException e) { outputFuture.cancel(false); } // at this point the return value doesn't matter since we already called setException or // cancel so the future is done. return null; } } private static final class CombinerFuture<V> extends ListenableFutureTask<V> { ImmutableList<ListenableFuture<?>> futures; CombinerFuture(Callable<V> callable, ImmutableList<ListenableFuture<?>> futures) { super(callable); this.futures = futures; } @Override public boolean cancel(boolean mayInterruptIfRunning) { ImmutableList<ListenableFuture<?>> futures = this.futures; if (super.cancel(mayInterruptIfRunning)) { for (ListenableFuture<?> future : futures) { future.cancel(mayInterruptIfRunning); } return true; } return false; } @Override protected void done() { super.done(); futures = null; } @Override protected void setException(Throwable t) { super.setException(t); } } /** * Creates a new {@code ListenableFuture} whose result is set from the * supplied future when it completes. Cancelling the supplied future * will also cancel the returned future, but cancelling the returned * future will have no effect on the supplied future. * * @since 15.0 */ public static <V> ListenableFuture<V> nonCancellationPropagating( ListenableFuture<V> future) { return new NonCancellationPropagatingFuture<V>(future); } /** * A wrapped future that does not propagate cancellation to its delegate. */ private static class NonCancellationPropagatingFuture<V> extends AbstractFuture<V> { NonCancellationPropagatingFuture(final ListenableFuture<V> delegate) { checkNotNull(delegate); addCallback(delegate, new FutureCallback<V>() { @Override public void onSuccess(V result) { set(result); } @Override public void onFailure(Throwable t) { if (delegate.isCancelled()) { cancel(false); } else { setException(t); } } }, directExecutor()); } } /** * Creates a new {@code ListenableFuture} whose value is a list containing the * values of all its successful input futures. The list of results is in the * same order as the input list, and if any of the provided futures fails or * is canceled, its corresponding position will contain {@code null} (which is * indistinguishable from the future having a successful value of * {@code null}). * * <p>Canceling this future will attempt to cancel all the component futures. * * @param futures futures to combine * @return a future that provides a list of the results of the component * futures * @since 10.0 */ @Beta public static <V> ListenableFuture<List<V>> successfulAsList( ListenableFuture<? extends V>... futures) { return listFuture(ImmutableList.copyOf(futures), false, directExecutor()); } /** * Creates a new {@code ListenableFuture} whose value is a list containing the * values of all its successful input futures. The list of results is in the * same order as the input list, and if any of the provided futures fails or * is canceled, its corresponding position will contain {@code null} (which is * indistinguishable from the future having a successful value of * {@code null}). * * <p>Canceling this future will attempt to cancel all the component futures. * * @param futures futures to combine * @return a future that provides a list of the results of the component * futures * @since 10.0 */ @Beta public static <V> ListenableFuture<List<V>> successfulAsList( Iterable<? extends ListenableFuture<? extends V>> futures) { return listFuture(ImmutableList.copyOf(futures), false, directExecutor()); } /** * Returns a list of delegate futures that correspond to the futures received in the order * that they complete. Delegate futures return the same value or throw the same exception * as the corresponding input future returns/throws. * * <p>Cancelling a delegate future has no effect on any input future, since the delegate future * does not correspond to a specific input future until the appropriate number of input * futures have completed. At that point, it is too late to cancel the input future. * The input future's result, which cannot be stored into the cancelled delegate future, * is ignored. * * @since 17.0 */ @Beta public static <T> ImmutableList<ListenableFuture<T>> inCompletionOrder( Iterable<? extends ListenableFuture<? extends T>> futures) { // A CLQ may be overkill here. We could save some pointers/memory by synchronizing on an // ArrayDeque final ConcurrentLinkedQueue<AsyncSettableFuture<T>> delegates = Queues.newConcurrentLinkedQueue(); ImmutableList.Builder<ListenableFuture<T>> listBuilder = ImmutableList.builder(); // Using SerializingExecutor here will ensure that each CompletionOrderListener executes // atomically and therefore that each returned future is guaranteed to be in completion order. // N.B. there are some cases where the use of this executor could have possibly surprising // effects when input futures finish at approximately the same time _and_ the output futures // have directExecutor listeners. In this situation, the listeners may end up running on a // different thread than if they were attached to the corresponding input future. We believe // this to be a negligible cost since: // 1. Using the directExecutor implies that your callback is safe to run on any thread. // 2. This would likely only be noticeable if you were doing something expensive or blocking on // a directExecutor listener on one of the output futures which is an antipattern anyway. SerializingExecutor executor = new SerializingExecutor(directExecutor()); for (final ListenableFuture<? extends T> future : futures) { AsyncSettableFuture<T> delegate = AsyncSettableFuture.create(); // Must make sure to add the delegate to the queue first in case the future is already done delegates.add(delegate); future.addListener(new Runnable() { @Override public void run() { delegates.remove().setFuture(future); } }, executor); listBuilder.add(delegate); } return listBuilder.build(); } /** * Registers separate success and failure callbacks to be run when the {@code * Future}'s computation is {@linkplain java.util.concurrent.Future#isDone() * complete} or, if the computation is already complete, immediately. * * <p>There is no guaranteed ordering of execution of callbacks, but any * callback added through this method is guaranteed to be called once the * computation is complete. * * Example: <pre> {@code * ListenableFuture<QueryResult> future = ...; * addCallback(future, * new FutureCallback<QueryResult> { * public void onSuccess(QueryResult result) { * storeInCache(result); * } * public void onFailure(Throwable t) { * reportError(t); * } * });}</pre> * * <p>Note: If the callback is slow or heavyweight, consider {@linkplain * #addCallback(ListenableFuture, FutureCallback, Executor) supplying an * executor}. If you do not supply an executor, {@code addCallback} will use * a {@linkplain MoreExecutors#directExecutor direct executor}, which carries * some caveats for heavier operations. For example, the callback may run on * an unpredictable or undesirable thread: * * <ul> * <li>If the input {@code Future} is done at the time {@code addCallback} is * called, {@code addCallback} will execute the callback inline. * <li>If the input {@code Future} is not yet done, {@code addCallback} will * schedule the callback to be run by the thread that completes the input * {@code Future}, which may be an internal system thread such as an RPC * network thread. * </ul> * * <p>Also note that, regardless of which thread executes the callback, all * other registered but unexecuted listeners are prevented from running * during its execution, even if those listeners are to run in other * executors. * * <p>For a more general interface to attach a completion listener to a * {@code Future}, see {@link ListenableFuture#addListener addListener}. * * @param future The future attach the callback to. * @param callback The callback to invoke when {@code future} is completed. * @since 10.0 */ public static <V> void addCallback(ListenableFuture<V> future, FutureCallback<? super V> callback) { addCallback(future, callback, directExecutor()); } /** * Registers separate success and failure callbacks to be run when the {@code * Future}'s computation is {@linkplain java.util.concurrent.Future#isDone() * complete} or, if the computation is already complete, immediately. * * <p>The callback is run in {@code executor}. * There is no guaranteed ordering of execution of callbacks, but any * callback added through this method is guaranteed to be called once the * computation is complete. * * Example: <pre> {@code * ListenableFuture<QueryResult> future = ...; * Executor e = ... * addCallback(future, * new FutureCallback<QueryResult> { * public void onSuccess(QueryResult result) { * storeInCache(result); * } * public void onFailure(Throwable t) { * reportError(t); * } * }, e);}</pre> * * <p>When the callback is fast and lightweight, consider {@linkplain * #addCallback(ListenableFuture, FutureCallback) omitting the executor} or * explicitly specifying {@code directExecutor}. However, be aware of the * caveats documented in the link above. * * <p>For a more general interface to attach a completion listener to a * {@code Future}, see {@link ListenableFuture#addListener addListener}. * * @param future The future attach the callback to. * @param callback The callback to invoke when {@code future} is completed. * @param executor The executor to run {@code callback} when the future * completes. * @since 10.0 */ public static <V> void addCallback(final ListenableFuture<V> future, final FutureCallback<? super V> callback, Executor executor) { Preconditions.checkNotNull(callback); Runnable callbackListener = new Runnable() { @Override public void run() { final V value; try { // TODO(user): (Before Guava release), validate that this // is the thing for IE. value = getUninterruptibly(future); } catch (ExecutionException e) { callback.onFailure(e.getCause()); return; } catch (RuntimeException e) { callback.onFailure(e); return; } catch (Error e) { callback.onFailure(e); return; } callback.onSuccess(value); } }; future.addListener(callbackListener, executor); } /** * Returns the result of {@link Future#get()}, converting most exceptions to a * new instance of the given checked exception type. This reduces boilerplate * for a common use of {@code Future} in which it is unnecessary to * programmatically distinguish between exception types or to extract other * information from the exception instance. * * <p>Exceptions from {@code Future.get} are treated as follows: * <ul> * <li>Any {@link ExecutionException} has its <i>cause</i> wrapped in an * {@code X} if the cause is a checked exception, an {@link * UncheckedExecutionException} if the cause is a {@code * RuntimeException}, or an {@link ExecutionError} if the cause is an * {@code Error}. * <li>Any {@link InterruptedException} is wrapped in an {@code X} (after * restoring the interrupt). * <li>Any {@link CancellationException} is propagated untouched, as is any * other {@link RuntimeException} (though {@code get} implementations are * discouraged from throwing such exceptions). * </ul> * * <p>The overall principle is to continue to treat every checked exception as a * checked exception, every unchecked exception as an unchecked exception, and * every error as an error. In addition, the cause of any {@code * ExecutionException} is wrapped in order to ensure that the new stack trace * matches that of the current thread. * * <p>Instances of {@code exceptionClass} are created by choosing an arbitrary * public constructor that accepts zero or more arguments, all of type {@code * String} or {@code Throwable} (preferring constructors with at least one * {@code String}) and calling the constructor via reflection. If the * exception did not already have a cause, one is set by calling {@link * Throwable#initCause(Throwable)} on it. If no such constructor exists, an * {@code IllegalArgumentException} is thrown. * * @throws X if {@code get} throws any checked exception except for an {@code * ExecutionException} whose cause is not itself a checked exception * @throws UncheckedExecutionException if {@code get} throws an {@code * ExecutionException} with a {@code RuntimeException} as its cause * @throws ExecutionError if {@code get} throws an {@code ExecutionException} * with an {@code Error} as its cause * @throws CancellationException if {@code get} throws a {@code * CancellationException} * @throws IllegalArgumentException if {@code exceptionClass} extends {@code * RuntimeException} or does not have a suitable constructor * @since 10.0 */ public static <V, X extends Exception> V get( Future<V> future, Class<X> exceptionClass) throws X { checkNotNull(future); checkArgument(!RuntimeException.class.isAssignableFrom(exceptionClass), "Futures.get exception type (%s) must not be a RuntimeException", exceptionClass); try { return future.get(); } catch (InterruptedException e) { currentThread().interrupt(); throw newWithCause(exceptionClass, e); } catch (ExecutionException e) { wrapAndThrowExceptionOrError(e.getCause(), exceptionClass); throw new AssertionError(); } } /** * Returns the result of {@link Future#get(long, TimeUnit)}, converting most * exceptions to a new instance of the given checked exception type. This * reduces boilerplate for a common use of {@code Future} in which it is * unnecessary to programmatically distinguish between exception types or to * extract other information from the exception instance. * * <p>Exceptions from {@code Future.get} are treated as follows: * <ul> * <li>Any {@link ExecutionException} has its <i>cause</i> wrapped in an * {@code X} if the cause is a checked exception, an {@link * UncheckedExecutionException} if the cause is a {@code * RuntimeException}, or an {@link ExecutionError} if the cause is an * {@code Error}. * <li>Any {@link InterruptedException} is wrapped in an {@code X} (after * restoring the interrupt). * <li>Any {@link TimeoutException} is wrapped in an {@code X}. * <li>Any {@link CancellationException} is propagated untouched, as is any * other {@link RuntimeException} (though {@code get} implementations are * discouraged from throwing such exceptions). * </ul> * * <p>The overall principle is to continue to treat every checked exception as a * checked exception, every unchecked exception as an unchecked exception, and * every error as an error. In addition, the cause of any {@code * ExecutionException} is wrapped in order to ensure that the new stack trace * matches that of the current thread. * * <p>Instances of {@code exceptionClass} are created by choosing an arbitrary * public constructor that accepts zero or more arguments, all of type {@code * String} or {@code Throwable} (preferring constructors with at least one * {@code String}) and calling the constructor via reflection. If the * exception did not already have a cause, one is set by calling {@link * Throwable#initCause(Throwable)} on it. If no such constructor exists, an * {@code IllegalArgumentException} is thrown. * * @throws X if {@code get} throws any checked exception except for an {@code * ExecutionException} whose cause is not itself a checked exception * @throws UncheckedExecutionException if {@code get} throws an {@code * ExecutionException} with a {@code RuntimeException} as its cause * @throws ExecutionError if {@code get} throws an {@code ExecutionException} * with an {@code Error} as its cause * @throws CancellationException if {@code get} throws a {@code * CancellationException} * @throws IllegalArgumentException if {@code exceptionClass} extends {@code * RuntimeException} or does not have a suitable constructor * @since 10.0 */ public static <V, X extends Exception> V get( Future<V> future, long timeout, TimeUnit unit, Class<X> exceptionClass) throws X { checkNotNull(future); checkNotNull(unit); checkArgument(!RuntimeException.class.isAssignableFrom(exceptionClass), "Futures.get exception type (%s) must not be a RuntimeException", exceptionClass); try { return future.get(timeout, unit); } catch (InterruptedException e) { currentThread().interrupt(); throw newWithCause(exceptionClass, e); } catch (TimeoutException e) { throw newWithCause(exceptionClass, e); } catch (ExecutionException e) { wrapAndThrowExceptionOrError(e.getCause(), exceptionClass); throw new AssertionError(); } } private static <X extends Exception> void wrapAndThrowExceptionOrError( Throwable cause, Class<X> exceptionClass) throws X { if (cause instanceof Error) { throw new ExecutionError((Error) cause); } if (cause instanceof RuntimeException) { throw new UncheckedExecutionException(cause); } throw newWithCause(exceptionClass, cause); } /** * Returns the result of calling {@link Future#get()} uninterruptibly on a * task known not to throw a checked exception. This makes {@code Future} more * suitable for lightweight, fast-running tasks that, barring bugs in the * code, will not fail. This gives it exception-handling behavior similar to * that of {@code ForkJoinTask.join}. * * <p>Exceptions from {@code Future.get} are treated as follows: * <ul> * <li>Any {@link ExecutionException} has its <i>cause</i> wrapped in an * {@link UncheckedExecutionException} (if the cause is an {@code * Exception}) or {@link ExecutionError} (if the cause is an {@code * Error}). * <li>Any {@link InterruptedException} causes a retry of the {@code get} * call. The interrupt is restored before {@code getUnchecked} returns. * <li>Any {@link CancellationException} is propagated untouched. So is any * other {@link RuntimeException} ({@code get} implementations are * discouraged from throwing such exceptions). * </ul> * * <p>The overall principle is to eliminate all checked exceptions: to loop to * avoid {@code InterruptedException}, to pass through {@code * CancellationException}, and to wrap any exception from the underlying * computation in an {@code UncheckedExecutionException} or {@code * ExecutionError}. * * <p>For an uninterruptible {@code get} that preserves other exceptions, see * {@link Uninterruptibles#getUninterruptibly(Future)}. * * @throws UncheckedExecutionException if {@code get} throws an {@code * ExecutionException} with an {@code Exception} as its cause * @throws ExecutionError if {@code get} throws an {@code ExecutionException} * with an {@code Error} as its cause * @throws CancellationException if {@code get} throws a {@code * CancellationException} * @since 10.0 */ public static <V> V getUnchecked(Future<V> future) { checkNotNull(future); try { return getUninterruptibly(future); } catch (ExecutionException e) { wrapAndThrowUnchecked(e.getCause()); throw new AssertionError(); } } private static void wrapAndThrowUnchecked(Throwable cause) { if (cause instanceof Error) { throw new ExecutionError((Error) cause); } /* * It's a non-Error, non-Exception Throwable. From my survey of such * classes, I believe that most users intended to extend Exception, so we'll * treat it like an Exception. */ throw new UncheckedExecutionException(cause); } /* * TODO(user): FutureChecker interface for these to be static methods on? If * so, refer to it in the (static-method) Futures.get documentation */ /* * Arguably we don't need a timed getUnchecked because any operation slow * enough to require a timeout is heavyweight enough to throw a checked * exception and therefore be inappropriate to use with getUnchecked. Further, * it's not clear that converting the checked TimeoutException to a * RuntimeException -- especially to an UncheckedExecutionException, since it * wasn't thrown by the computation -- makes sense, and if we don't convert * it, the user still has to write a try-catch block. * * If you think you would use this method, let us know. */ private static <X extends Exception> X newWithCause( Class<X> exceptionClass, Throwable cause) { // getConstructors() guarantees this as long as we don't modify the array. @SuppressWarnings("unchecked") List<Constructor<X>> constructors = (List) Arrays.asList(exceptionClass.getConstructors()); for (Constructor<X> constructor : preferringStrings(constructors)) { @Nullable X instance = newFromConstructor(constructor, cause); if (instance != null) { if (instance.getCause() == null) { instance.initCause(cause); } return instance; } } throw new IllegalArgumentException( "No appropriate constructor for exception of type " + exceptionClass + " in response to chained exception", cause); } private static <X extends Exception> List<Constructor<X>> preferringStrings(List<Constructor<X>> constructors) { return WITH_STRING_PARAM_FIRST.sortedCopy(constructors); } private static final Ordering<Constructor<?>> WITH_STRING_PARAM_FIRST = Ordering.natural().onResultOf(new Function<Constructor<?>, Boolean>() { @Override public Boolean apply(Constructor<?> input) { return asList(input.getParameterTypes()).contains(String.class); } }).reverse(); @Nullable private static <X> X newFromConstructor( Constructor<X> constructor, Throwable cause) { Class<?>[] paramTypes = constructor.getParameterTypes(); Object[] params = new Object[paramTypes.length]; for (int i = 0; i < paramTypes.length; i++) { Class<?> paramType = paramTypes[i]; if (paramType.equals(String.class)) { params[i] = cause.toString(); } else if (paramType.equals(Throwable.class)) { params[i] = cause; } else { return null; } } try { return constructor.newInstance(params); } catch (IllegalArgumentException e) { return null; } catch (InstantiationException e) { return null; } catch (IllegalAccessException e) { return null; } catch (InvocationTargetException e) { return null; } } private interface FutureCombiner<V, C> { C combine(List<Optional<V>> values); } private static class CombinedFuture<V, C> extends AbstractFuture<C> { private static final Logger logger = Logger.getLogger(CombinedFuture.class.getName()); ImmutableCollection<? extends ListenableFuture<? extends V>> futures; final boolean allMustSucceed; final AtomicInteger remaining; FutureCombiner<V, C> combiner; List<Optional<V>> values; final Object seenExceptionsLock = new Object(); Set<Throwable> seenExceptions; CombinedFuture( ImmutableCollection<? extends ListenableFuture<? extends V>> futures, boolean allMustSucceed, Executor listenerExecutor, FutureCombiner<V, C> combiner) { this.futures = futures; this.allMustSucceed = allMustSucceed; this.remaining = new AtomicInteger(futures.size()); this.combiner = combiner; this.values = Lists.newArrayListWithCapacity(futures.size()); init(listenerExecutor); } /** * Must be called at the end of the constructor. */ protected void init(final Executor listenerExecutor) { // First, schedule cleanup to execute when the Future is done. addListener(new Runnable() { @Override public void run() { // Cancel all the component futures. if (CombinedFuture.this.isCancelled()) { for (ListenableFuture<?> future : CombinedFuture.this.futures) { future.cancel(CombinedFuture.this.wasInterrupted()); } } // Let go of the memory held by other futures CombinedFuture.this.futures = null; // By now the values array has either been set as the Future's value, // or (in case of failure) is no longer useful. CombinedFuture.this.values = null; // The combiner may also hold state, so free that as well CombinedFuture.this.combiner = null; } }, directExecutor()); // Now begin the "real" initialization. // Corner case: List is empty. if (futures.isEmpty()) { set(combiner.combine(ImmutableList.<Optional<V>>of())); return; } // Populate the results list with null initially. for (int i = 0; i < futures.size(); ++i) { values.add(null); } // Register a listener on each Future in the list to update // the state of this future. // Note that if all the futures on the list are done prior to completing // this loop, the last call to addListener() will callback to // setOneValue(), transitively call our cleanup listener, and set // this.futures to null. // This is not actually a problem, since the foreach only needs // this.futures to be non-null at the beginning of the loop. int i = 0; for (final ListenableFuture<? extends V> listenable : futures) { final int index = i++; listenable.addListener(new Runnable() { @Override public void run() { setOneValue(index, listenable); } }, listenerExecutor); } } /** * Fails this future with the given Throwable if {@link #allMustSucceed} is * true. Also, logs the throwable if it is an {@link Error} or if * {@link #allMustSucceed} is {@code true}, the throwable did not cause * this future to fail, and it is the first time we've seen that particular Throwable. */ private void setExceptionAndMaybeLog(Throwable throwable) { boolean visibleFromOutputFuture = false; boolean firstTimeSeeingThisException = true; if (allMustSucceed) { // As soon as the first one fails, throw the exception up. // The result of all other inputs is then ignored. visibleFromOutputFuture = super.setException(throwable); synchronized (seenExceptionsLock) { if (seenExceptions == null) { seenExceptions = Sets.newHashSet(); } firstTimeSeeingThisException = seenExceptions.add(throwable); } } if (throwable instanceof Error || (allMustSucceed && !visibleFromOutputFuture && firstTimeSeeingThisException)) { logger.log(Level.SEVERE, "input future failed.", throwable); } } /** * Sets the value at the given index to that of the given future. */ private void setOneValue(int index, Future<? extends V> future) { List<Optional<V>> localValues = values; // TODO(user): This check appears to be redundant since values is // assigned null only after the future completes. However, values // is not volatile so it may be possible for us to observe the changes // to these two values in a different order... which I think is why // we need to check both. Clear up this craziness either by making // values volatile or proving that it doesn't need to be for some other // reason. if (isDone() || localValues == null) { // Some other future failed or has been cancelled, causing this one to // also be cancelled or have an exception set. This should only happen // if allMustSucceed is true or if the output itself has been // cancelled. checkState(allMustSucceed || isCancelled(), "Future was done before all dependencies completed"); } try { checkState(future.isDone(), "Tried to set value from future which is not done"); V returnValue = getUninterruptibly(future); if (localValues != null) { localValues.set(index, Optional.fromNullable(returnValue)); } } catch (CancellationException e) { if (allMustSucceed) { // Set ourselves as cancelled. Let the input futures keep running // as some of them may be used elsewhere. cancel(false); } } catch (ExecutionException e) { setExceptionAndMaybeLog(e.getCause()); } catch (Throwable t) { setExceptionAndMaybeLog(t); } finally { int newRemaining = remaining.decrementAndGet(); checkState(newRemaining >= 0, "Less than 0 remaining futures"); if (newRemaining == 0) { FutureCombiner<V, C> localCombiner = combiner; if (localCombiner != null && localValues != null) { set(localCombiner.combine(localValues)); } else { checkState(isDone()); } } } } } /** Used for {@link #allAsList} and {@link #successfulAsList}. */ private static <V> ListenableFuture<List<V>> listFuture( ImmutableList<ListenableFuture<? extends V>> futures, boolean allMustSucceed, Executor listenerExecutor) { return new CombinedFuture<V, List<V>>( futures, allMustSucceed, listenerExecutor, new FutureCombiner<V, List<V>>() { @Override public List<V> combine(List<Optional<V>> values) { List<V> result = Lists.newArrayList(); for (Optional<V> element : values) { result.add(element != null ? element.orNull() : null); } return Collections.unmodifiableList(result); } }); } /** * A checked future that uses a function to map from exceptions to the * appropriate checked type. */ private static class MappingCheckedFuture<V, X extends Exception> extends AbstractCheckedFuture<V, X> { final Function<? super Exception, X> mapper; MappingCheckedFuture(ListenableFuture<V> delegate, Function<? super Exception, X> mapper) { super(delegate); this.mapper = checkNotNull(mapper); } @Override protected X mapException(Exception e) { return mapper.apply(e); } } }