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