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