001/*
002 * Copyright (C) 2006 The Guava Authors
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
005 * in compliance with the License. You may obtain a copy of the License at
006 *
007 * http://www.apache.org/licenses/LICENSE-2.0
008 *
009 * Unless required by applicable law or agreed to in writing, software distributed under the License
010 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
011 * or implied. See the License for the specific language governing permissions and limitations under
012 * the License.
013 */
014
015package com.google.common.util.concurrent;
016
017import static com.google.common.base.Preconditions.checkNotNull;
018
019import com.google.common.annotations.Beta;
020import com.google.common.annotations.GwtCompatible;
021import com.google.common.annotations.GwtIncompatible;
022import com.google.common.base.Function;
023import com.google.errorprone.annotations.CanIgnoreReturnValue;
024import com.google.errorprone.annotations.DoNotMock;
025import java.util.concurrent.ExecutionException;
026import java.util.concurrent.Executor;
027import java.util.concurrent.ScheduledExecutorService;
028import java.util.concurrent.TimeUnit;
029import java.util.concurrent.TimeoutException;
030import org.checkerframework.checker.nullness.qual.Nullable;
031
032/**
033 * A {@link ListenableFuture} that supports fluent chains of operations. For example:
034 *
035 * <pre>{@code
036 * ListenableFuture<Boolean> adminIsLoggedIn =
037 *     FluentFuture.from(usersDatabase.getAdminUser())
038 *         .transform(User::getId, directExecutor())
039 *         .transform(ActivityService::isLoggedIn, threadPool)
040 *         .catching(RpcException.class, e -> false, directExecutor());
041 * }</pre>
042 *
043 * <h3>Alternatives</h3>
044 *
045 * <h4>Frameworks</h4>
046 *
047 * <p>When chaining together a graph of asynchronous operations, you will often find it easier to
048 * use a framework. Frameworks automate the process, often adding features like monitoring,
049 * debugging, and cancellation. Examples of frameworks include:
050 *
051 * <ul>
052 *   <li><a href="https://dagger.dev/producers.html">Dagger Producers</a>
053 * </ul>
054 *
055 * <h4>{@link java.util.concurrent.CompletableFuture} / {@link java.util.concurrent.CompletionStage}
056 * </h4>
057 *
058 * <p>Users of {@code CompletableFuture} will likely want to continue using {@code
059 * CompletableFuture}. {@code FluentFuture} is targeted at people who use {@code ListenableFuture},
060 * who can't use Java 8, or who want an API more focused than {@code CompletableFuture}. (If you
061 * need to adapt between {@code CompletableFuture} and {@code ListenableFuture}, consider <a
062 * href="https://github.com/lukas-krecan/future-converter">Future Converter</a>.)
063 *
064 * <h3>Extension</h3>
065 *
066 * If you want a class like {@code FluentFuture} but with extra methods, we recommend declaring your
067 * own subclass of {@link ListenableFuture}, complete with a method like {@link #from} to adapt an
068 * existing {@code ListenableFuture}, implemented atop a {@link ForwardingListenableFuture} that
069 * forwards to that future and adds the desired methods.
070 *
071 * @since 23.0
072 */
073@DoNotMock("Use FluentFuture.from(Futures.immediate*Future) or SettableFuture")
074@GwtCompatible(emulated = true)
075@ElementTypesAreNonnullByDefault
076public abstract class FluentFuture<V extends @Nullable Object>
077    extends GwtFluentFutureCatchingSpecialization<V> {
078
079  /**
080   * A less abstract subclass of AbstractFuture. This can be used to optimize setFuture by ensuring
081   * that {@link #get} calls exactly the implementation of {@link AbstractFuture#get}.
082   */
083  abstract static class TrustedFuture<V extends @Nullable Object> extends FluentFuture<V>
084      implements AbstractFuture.Trusted<V> {
085    @CanIgnoreReturnValue
086    @Override
087    @ParametricNullness
088    public final V get() throws InterruptedException, ExecutionException {
089      return super.get();
090    }
091
092    @CanIgnoreReturnValue
093    @Override
094    @ParametricNullness
095    public final V get(long timeout, TimeUnit unit)
096        throws InterruptedException, ExecutionException, TimeoutException {
097      return super.get(timeout, unit);
098    }
099
100    @Override
101    public final boolean isDone() {
102      return super.isDone();
103    }
104
105    @Override
106    public final boolean isCancelled() {
107      return super.isCancelled();
108    }
109
110    @Override
111    public final void addListener(Runnable listener, Executor executor) {
112      super.addListener(listener, executor);
113    }
114
115    @CanIgnoreReturnValue
116    @Override
117    public final boolean cancel(boolean mayInterruptIfRunning) {
118      return super.cancel(mayInterruptIfRunning);
119    }
120  }
121
122  FluentFuture() {}
123
124  /**
125   * Converts the given {@code ListenableFuture} to an equivalent {@code FluentFuture}.
126   *
127   * <p>If the given {@code ListenableFuture} is already a {@code FluentFuture}, it is returned
128   * directly. If not, it is wrapped in a {@code FluentFuture} that delegates all calls to the
129   * original {@code ListenableFuture}.
130   */
131  public static <V extends @Nullable Object> FluentFuture<V> from(ListenableFuture<V> future) {
132    return future instanceof FluentFuture
133        ? (FluentFuture<V>) future
134        : new ForwardingFluentFuture<V>(future);
135  }
136
137  /**
138   * Simply returns its argument.
139   *
140   * @deprecated no need to use this
141   * @since 28.0
142   */
143  @Deprecated
144  public static <V extends @Nullable Object> FluentFuture<V> from(FluentFuture<V> future) {
145    return checkNotNull(future);
146  }
147
148  /**
149   * Returns a {@code Future} whose result is taken from this {@code Future} or, if this {@code
150   * Future} fails with the given {@code exceptionType}, from the result provided by the {@code
151   * fallback}. {@link Function#apply} is not invoked until the primary input has failed, so if the
152   * primary input succeeds, it is never invoked. If, during the invocation of {@code fallback}, an
153   * exception is thrown, this exception is used as the result of the output {@code Future}.
154   *
155   * <p>Usage example:
156   *
157   * <pre>{@code
158   * // Falling back to a zero counter in case an exception happens when processing the RPC to fetch
159   * // counters.
160   * ListenableFuture<Integer> faultTolerantFuture =
161   *     fetchCounters().catching(FetchException.class, x -> 0, directExecutor());
162   * }</pre>
163   *
164   * <p>When selecting an executor, note that {@code directExecutor} is dangerous in some cases. See
165   * the discussion in the {@link #addListener} documentation. All its warnings about heavyweight
166   * listeners are also applicable to heavyweight functions passed to this method.
167   *
168   * <p>This method is similar to {@link java.util.concurrent.CompletableFuture#exceptionally}. It
169   * can also serve some of the use cases of {@link java.util.concurrent.CompletableFuture#handle}
170   * and {@link java.util.concurrent.CompletableFuture#handleAsync} when used along with {@link
171   * #transform}.
172   *
173   * @param exceptionType the exception type that triggers use of {@code fallback}. The exception
174   *     type is matched against the input's exception. "The input's exception" means the cause of
175   *     the {@link ExecutionException} thrown by {@code input.get()} or, if {@code get()} throws a
176   *     different kind of exception, that exception itself. To avoid hiding bugs and other
177   *     unrecoverable errors, callers should prefer more specific types, avoiding {@code
178   *     Throwable.class} in particular.
179   * @param fallback the {@link Function} to be called if the input fails with the expected
180   *     exception type. The function's argument is the input's exception. "The input's exception"
181   *     means the cause of the {@link ExecutionException} thrown by {@code this.get()} or, if
182   *     {@code get()} throws a different kind of exception, that exception itself.
183   * @param executor the executor that runs {@code fallback} if the input fails
184   */
185  @Partially.GwtIncompatible("AVAILABLE but requires exceptionType to be Throwable.class")
186  @Beta
187  public final <X extends Throwable> FluentFuture<V> catching(
188      Class<X> exceptionType, Function<? super X, ? extends V> fallback, Executor executor) {
189    return (FluentFuture<V>) Futures.catching(this, exceptionType, fallback, executor);
190  }
191
192  /**
193   * Returns a {@code Future} whose result is taken from this {@code Future} or, if this {@code
194   * Future} fails with the given {@code exceptionType}, from the result provided by the {@code
195   * fallback}. {@link AsyncFunction#apply} is not invoked until the primary input has failed, so if
196   * the primary input succeeds, it is never invoked. If, during the invocation of {@code fallback},
197   * an exception is thrown, this exception is used as the result of the output {@code Future}.
198   *
199   * <p>Usage examples:
200   *
201   * <pre>{@code
202   * // Falling back to a zero counter in case an exception happens when processing the RPC to fetch
203   * // counters.
204   * ListenableFuture<Integer> faultTolerantFuture =
205   *     fetchCounters().catchingAsync(
206   *         FetchException.class, x -> immediateFuture(0), directExecutor());
207   * }</pre>
208   *
209   * <p>The fallback can also choose to propagate the original exception when desired:
210   *
211   * <pre>{@code
212   * // Falling back to a zero counter only in case the exception was a
213   * // TimeoutException.
214   * ListenableFuture<Integer> faultTolerantFuture =
215   *     fetchCounters().catchingAsync(
216   *         FetchException.class,
217   *         e -> {
218   *           if (omitDataOnFetchFailure) {
219   *             return immediateFuture(0);
220   *           }
221   *           throw e;
222   *         },
223   *         directExecutor());
224   * }</pre>
225   *
226   * <p>When selecting an executor, note that {@code directExecutor} is dangerous in some cases. See
227   * the discussion in the {@link #addListener} documentation. All its warnings about heavyweight
228   * listeners are also applicable to heavyweight functions passed to this method. (Specifically,
229   * {@code directExecutor} functions should avoid heavyweight operations inside {@code
230   * AsyncFunction.apply}. Any heavyweight operations should occur in other threads responsible for
231   * completing the returned {@code Future}.)
232   *
233   * <p>This method is similar to {@link java.util.concurrent.CompletableFuture#exceptionally}. It
234   * can also serve some of the use cases of {@link java.util.concurrent.CompletableFuture#handle}
235   * and {@link java.util.concurrent.CompletableFuture#handleAsync} when used along with {@link
236   * #transform}.
237   *
238   * @param exceptionType the exception type that triggers use of {@code fallback}. The exception
239   *     type is matched against the input's exception. "The input's exception" means the cause of
240   *     the {@link ExecutionException} thrown by {@code this.get()} or, if {@code get()} throws a
241   *     different kind of exception, that exception itself. To avoid hiding bugs and other
242   *     unrecoverable errors, callers should prefer more specific types, avoiding {@code
243   *     Throwable.class} in particular.
244   * @param fallback the {@link AsyncFunction} to be called if the input fails with the expected
245   *     exception type. The function's argument is the input's exception. "The input's exception"
246   *     means the cause of the {@link ExecutionException} thrown by {@code input.get()} or, if
247   *     {@code get()} throws a different kind of exception, that exception itself.
248   * @param executor the executor that runs {@code fallback} if the input fails
249   */
250  @Partially.GwtIncompatible("AVAILABLE but requires exceptionType to be Throwable.class")
251  @Beta
252  public final <X extends Throwable> FluentFuture<V> catchingAsync(
253      Class<X> exceptionType, AsyncFunction<? super X, ? extends V> fallback, Executor executor) {
254    return (FluentFuture<V>) Futures.catchingAsync(this, exceptionType, fallback, executor);
255  }
256
257  /**
258   * Returns a future that delegates to this future but will finish early (via a {@link
259   * TimeoutException} wrapped in an {@link ExecutionException}) if the specified timeout expires.
260   * If the timeout expires, not only will the output future finish, but also the input future
261   * ({@code this}) will be cancelled and interrupted.
262   *
263   * @param timeout when to time out the future
264   * @param unit the time unit of the time parameter
265   * @param scheduledExecutor The executor service to enforce the timeout.
266   */
267  @GwtIncompatible // ScheduledExecutorService
268  @SuppressWarnings("GoodTime") // should accept a java.time.Duration
269  @Beta
270  public final FluentFuture<V> withTimeout(
271      long timeout, TimeUnit unit, ScheduledExecutorService scheduledExecutor) {
272    return (FluentFuture<V>) Futures.withTimeout(this, timeout, unit, scheduledExecutor);
273  }
274
275  /**
276   * Returns a new {@code Future} whose result is asynchronously derived from the result of this
277   * {@code Future}. If the input {@code Future} fails, the returned {@code Future} fails with the
278   * same exception (and the function is not invoked).
279   *
280   * <p>More precisely, the returned {@code Future} takes its result from a {@code Future} produced
281   * by applying the given {@code AsyncFunction} to the result of the original {@code Future}.
282   * Example usage:
283   *
284   * <pre>{@code
285   * FluentFuture<RowKey> rowKeyFuture = FluentFuture.from(indexService.lookUp(query));
286   * ListenableFuture<QueryResult> queryFuture =
287   *     rowKeyFuture.transformAsync(dataService::readFuture, executor);
288   * }</pre>
289   *
290   * <p>When selecting an executor, note that {@code directExecutor} is dangerous in some cases. See
291   * the discussion in the {@link #addListener} documentation. All its warnings about heavyweight
292   * listeners are also applicable to heavyweight functions passed to this method. (Specifically,
293   * {@code directExecutor} functions should avoid heavyweight operations inside {@code
294   * AsyncFunction.apply}. Any heavyweight operations should occur in other threads responsible for
295   * completing the returned {@code Future}.)
296   *
297   * <p>The returned {@code Future} attempts to keep its cancellation state in sync with that of the
298   * input future and that of the future returned by the chain function. That is, if the returned
299   * {@code Future} is cancelled, it will attempt to cancel the other two, and if either of the
300   * other two is cancelled, the returned {@code Future} will receive a callback in which it will
301   * attempt to cancel itself.
302   *
303   * <p>This method is similar to {@link java.util.concurrent.CompletableFuture#thenCompose} and
304   * {@link java.util.concurrent.CompletableFuture#thenComposeAsync}. It can also serve some of the
305   * use cases of {@link java.util.concurrent.CompletableFuture#handle} and {@link
306   * java.util.concurrent.CompletableFuture#handleAsync} when used along with {@link #catching}.
307   *
308   * @param function A function to transform the result of this future to the result of the output
309   *     future
310   * @param executor Executor to run the function in.
311   * @return A future that holds result of the function (if the input succeeded) or the original
312   *     input's failure (if not)
313   */
314  @Beta
315  public final <T extends @Nullable Object> FluentFuture<T> transformAsync(
316      AsyncFunction<? super V, T> function, Executor executor) {
317    return (FluentFuture<T>) Futures.transformAsync(this, function, executor);
318  }
319
320  /**
321   * Returns a new {@code Future} whose result is derived from the result of this {@code Future}. If
322   * this input {@code Future} fails, the returned {@code Future} fails with the same exception (and
323   * the function is not invoked). Example usage:
324   *
325   * <pre>{@code
326   * ListenableFuture<List<Row>> rowsFuture =
327   *     queryFuture.transform(QueryResult::getRows, executor);
328   * }</pre>
329   *
330   * <p>When selecting an executor, note that {@code directExecutor} is dangerous in some cases. See
331   * the discussion in the {@link #addListener} documentation. All its warnings about heavyweight
332   * listeners are also applicable to heavyweight functions passed to this method.
333   *
334   * <p>The returned {@code Future} attempts to keep its cancellation state in sync with that of the
335   * input future. That is, if the returned {@code Future} is cancelled, it will attempt to cancel
336   * the input, and if the input is cancelled, the returned {@code Future} will receive a callback
337   * in which it will attempt to cancel itself.
338   *
339   * <p>An example use of this method is to convert a serializable object returned from an RPC into
340   * a POJO.
341   *
342   * <p>This method is similar to {@link java.util.concurrent.CompletableFuture#thenApply} and
343   * {@link java.util.concurrent.CompletableFuture#thenApplyAsync}. It can also serve some of the
344   * use cases of {@link java.util.concurrent.CompletableFuture#handle} and {@link
345   * java.util.concurrent.CompletableFuture#handleAsync} when used along with {@link #catching}.
346   *
347   * @param function A Function to transform the results of this future to the results of the
348   *     returned future.
349   * @param executor Executor to run the function in.
350   * @return A future that holds result of the transformation.
351   */
352  @Beta
353  public final <T extends @Nullable Object> FluentFuture<T> transform(
354      Function<? super V, T> function, Executor executor) {
355    return (FluentFuture<T>) Futures.transform(this, function, executor);
356  }
357
358  /**
359   * Registers separate success and failure callbacks to be run when this {@code Future}'s
360   * computation is {@linkplain java.util.concurrent.Future#isDone() complete} or, if the
361   * computation is already complete, immediately.
362   *
363   * <p>The callback is run on {@code executor}. There is no guaranteed ordering of execution of
364   * callbacks, but any callback added through this method is guaranteed to be called once the
365   * computation is complete.
366   *
367   * <p>Example:
368   *
369   * <pre>{@code
370   * future.addCallback(
371   *     new FutureCallback<QueryResult>() {
372   *       public void onSuccess(QueryResult result) {
373   *         storeInCache(result);
374   *       }
375   *       public void onFailure(Throwable t) {
376   *         reportError(t);
377   *       }
378   *     }, executor);
379   * }</pre>
380   *
381   * <p>When selecting an executor, note that {@code directExecutor} is dangerous in some cases. See
382   * the discussion in the {@link #addListener} documentation. All its warnings about heavyweight
383   * listeners are also applicable to heavyweight callbacks passed to this method.
384   *
385   * <p>For a more general interface to attach a completion listener, see {@link #addListener}.
386   *
387   * <p>This method is similar to {@link java.util.concurrent.CompletableFuture#whenComplete} and
388   * {@link java.util.concurrent.CompletableFuture#whenCompleteAsync}. It also serves the use case
389   * of {@link java.util.concurrent.CompletableFuture#thenAccept} and {@link
390   * java.util.concurrent.CompletableFuture#thenAcceptAsync}.
391   *
392   * @param callback The callback to invoke when this {@code Future} is completed.
393   * @param executor The executor to run {@code callback} when the future completes.
394   */
395  public final void addCallback(FutureCallback<? super V> callback, Executor executor) {
396    Futures.addCallback(this, callback, executor);
397  }
398}