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