Coverage Summary for Class: FluentFuture (com.google.common.util.concurrent)

Class Method, % Line, %
FluentFuture 10% (1/10) 7.7% (1/13)
FluentFuture$TrustedFuture 85.7% (6/7) 75% (6/8)
Total 41.2% (7/17) 33.3% (7/21)


1 /* 2  * Copyright (C) 2006 The Guava Authors 3  * 4  * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5  * in compliance with the License. You may obtain a copy of the License at 6  * 7  * http://www.apache.org/licenses/LICENSE-2.0 8  * 9  * Unless required by applicable law or agreed to in writing, software distributed under the License 10  * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11  * or implied. See the License for the specific language governing permissions and limitations under 12  * the License. 13  */ 14  15 package com.google.common.util.concurrent; 16  17 import static com.google.common.base.Preconditions.checkNotNull; 18 import static com.google.common.util.concurrent.Internal.toNanosSaturated; 19  20 import com.google.common.annotations.Beta; 21 import com.google.common.annotations.GwtCompatible; 22 import com.google.common.annotations.GwtIncompatible; 23 import com.google.common.base.Function; 24 import com.google.errorprone.annotations.CanIgnoreReturnValue; 25 import com.google.errorprone.annotations.DoNotMock; 26 import java.time.Duration; 27 import java.util.concurrent.ExecutionException; 28 import java.util.concurrent.Executor; 29 import java.util.concurrent.ScheduledExecutorService; 30 import java.util.concurrent.TimeUnit; 31 import java.util.concurrent.TimeoutException; 32 import org.checkerframework.checker.nullness.qual.Nullable; 33  34 /** 35  * A {@link ListenableFuture} that supports fluent chains of operations. For example: 36  * 37  * <pre>{@code 38  * ListenableFuture<Boolean> adminIsLoggedIn = 39  * FluentFuture.from(usersDatabase.getAdminUser()) 40  * .transform(User::getId, directExecutor()) 41  * .transform(ActivityService::isLoggedIn, threadPool) 42  * .catching(RpcException.class, e -> false, directExecutor()); 43  * }</pre> 44  * 45  * <h3>Alternatives</h3> 46  * 47  * <h4>Frameworks</h4> 48  * 49  * <p>When chaining together a graph of asynchronous operations, you will often find it easier to 50  * use a framework. Frameworks automate the process, often adding features like monitoring, 51  * debugging, and cancellation. Examples of frameworks include: 52  * 53  * <ul> 54  * <li><a href="https://dagger.dev/producers.html">Dagger Producers</a> 55  * </ul> 56  * 57  * <h4>{@link java.util.concurrent.CompletableFuture} / {@link java.util.concurrent.CompletionStage} 58  * </h4> 59  * 60  * <p>Users of {@code CompletableFuture} will likely want to continue using {@code 61  * CompletableFuture}. {@code FluentFuture} is targeted at people who use {@code ListenableFuture}, 62  * who can't use Java 8, or who want an API more focused than {@code CompletableFuture}. (If you 63  * need to adapt between {@code CompletableFuture} and {@code ListenableFuture}, consider <a 64  * href="https://github.com/lukas-krecan/future-converter">Future Converter</a>.) 65  * 66  * <h3>Extension</h3> 67  * 68  * If you want a class like {@code FluentFuture} but with extra methods, we recommend declaring your 69  * own subclass of {@link ListenableFuture}, complete with a method like {@link #from} to adapt an 70  * existing {@code ListenableFuture}, implemented atop a {@link ForwardingListenableFuture} that 71  * forwards to that future and adds the desired methods. 72  * 73  * @since 23.0 74  */ 75 @Beta 76 @DoNotMock("Use FluentFuture.from(Futures.immediate*Future) or SettableFuture") 77 @GwtCompatible(emulated = true) 78 @ElementTypesAreNonnullByDefault 79 public abstract class FluentFuture<V extends @Nullable Object> 80  extends GwtFluentFutureCatchingSpecialization<V> { 81  82  /** 83  * A less abstract subclass of AbstractFuture. This can be used to optimize setFuture by ensuring 84  * that {@link #get} calls exactly the implementation of {@link AbstractFuture#get}. 85  */ 86  abstract static class TrustedFuture<V extends @Nullable Object> extends FluentFuture<V> 87  implements AbstractFuture.Trusted<V> { 88  @CanIgnoreReturnValue 89  @Override 90  @ParametricNullness 91  public final V get() throws InterruptedException, ExecutionException { 92  return super.get(); 93  } 94  95  @CanIgnoreReturnValue 96  @Override 97  @ParametricNullness 98  public final V get(long timeout, TimeUnit unit) 99  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  @Deprecated 147  public static <V extends @Nullable Object> FluentFuture<V> from(FluentFuture<V> future) { 148  return checkNotNull(future); 149  } 150  151  /** 152  * Returns a {@code Future} whose result is taken from this {@code Future} or, if this {@code 153  * Future} fails with the given {@code exceptionType}, from the result provided by the {@code 154  * fallback}. {@link Function#apply} is not invoked until the primary input has failed, so if the 155  * primary input succeeds, it is never invoked. If, during the invocation of {@code fallback}, an 156  * exception is thrown, this exception is used as the result of the output {@code Future}. 157  * 158  * <p>Usage example: 159  * 160  * <pre>{@code 161  * // Falling back to a zero counter in case an exception happens when processing the RPC to fetch 162  * // counters. 163  * ListenableFuture<Integer> faultTolerantFuture = 164  * fetchCounters().catching(FetchException.class, x -> 0, directExecutor()); 165  * }</pre> 166  * 167  * <p>When selecting an executor, note that {@code directExecutor} is dangerous in some cases. See 168  * the discussion in the {@link #addListener} documentation. All its warnings about heavyweight 169  * listeners are also applicable to heavyweight functions passed to this method. 170  * 171  * <p>This method is similar to {@link java.util.concurrent.CompletableFuture#exceptionally}. It 172  * can also serve some of the use cases of {@link java.util.concurrent.CompletableFuture#handle} 173  * and {@link java.util.concurrent.CompletableFuture#handleAsync} when used along with {@link 174  * #transform}. 175  * 176  * @param exceptionType the exception type that triggers use of {@code fallback}. The exception 177  * type is matched against the input's exception. "The input's exception" means the cause of 178  * the {@link ExecutionException} thrown by {@code input.get()} or, if {@code get()} throws a 179  * different kind of exception, that exception itself. To avoid hiding bugs and other 180  * unrecoverable errors, callers should prefer more specific types, avoiding {@code 181  * Throwable.class} in particular. 182  * @param fallback the {@link Function} to be called if the input fails with the expected 183  * exception type. The function's argument is the input's exception. "The input's exception" 184  * means the cause of the {@link ExecutionException} thrown by {@code this.get()} or, if 185  * {@code get()} throws a different kind of exception, that exception itself. 186  * @param executor the executor that runs {@code fallback} if the input fails 187  */ 188  @Partially.GwtIncompatible("AVAILABLE but requires exceptionType to be Throwable.class") 189  public final <X extends Throwable> FluentFuture<V> catching( 190  Class<X> exceptionType, Function<? super X, ? extends V> fallback, Executor executor) { 191  return (FluentFuture<V>) Futures.catching(this, exceptionType, fallback, executor); 192  } 193  194  /** 195  * Returns a {@code Future} whose result is taken from this {@code Future} or, if this {@code 196  * Future} fails with the given {@code exceptionType}, from the result provided by the {@code 197  * fallback}. {@link AsyncFunction#apply} is not invoked until the primary input has failed, so if 198  * the primary input succeeds, it is never invoked. If, during the invocation of {@code fallback}, 199  * an exception is thrown, this exception is used as the result of the output {@code Future}. 200  * 201  * <p>Usage examples: 202  * 203  * <pre>{@code 204  * // Falling back to a zero counter in case an exception happens when processing the RPC to fetch 205  * // counters. 206  * ListenableFuture<Integer> faultTolerantFuture = 207  * fetchCounters().catchingAsync( 208  * FetchException.class, x -> immediateFuture(0), directExecutor()); 209  * }</pre> 210  * 211  * <p>The fallback can also choose to propagate the original exception when desired: 212  * 213  * <pre>{@code 214  * // Falling back to a zero counter only in case the exception was a 215  * // TimeoutException. 216  * ListenableFuture<Integer> faultTolerantFuture = 217  * fetchCounters().catchingAsync( 218  * FetchException.class, 219  * e -> { 220  * if (omitDataOnFetchFailure) { 221  * return immediateFuture(0); 222  * } 223  * throw e; 224  * }, 225  * directExecutor()); 226  * }</pre> 227  * 228  * <p>When selecting an executor, note that {@code directExecutor} is dangerous in some cases. See 229  * the discussion in the {@link #addListener} documentation. All its warnings about heavyweight 230  * listeners are also applicable to heavyweight functions passed to this method. (Specifically, 231  * {@code directExecutor} functions should avoid heavyweight operations inside {@code 232  * AsyncFunction.apply}. Any heavyweight operations should occur in other threads responsible for 233  * completing the returned {@code Future}.) 234  * 235  * <p>This method is similar to {@link java.util.concurrent.CompletableFuture#exceptionally}. It 236  * can also serve some of the use cases of {@link java.util.concurrent.CompletableFuture#handle} 237  * and {@link java.util.concurrent.CompletableFuture#handleAsync} when used along with {@link 238  * #transform}. 239  * 240  * @param exceptionType the exception type that triggers use of {@code fallback}. The exception 241  * type is matched against the input's exception. "The input's exception" means the cause of 242  * the {@link ExecutionException} thrown by {@code this.get()} or, if {@code get()} throws a 243  * different kind of exception, that exception itself. To avoid hiding bugs and other 244  * unrecoverable errors, callers should prefer more specific types, avoiding {@code 245  * Throwable.class} in particular. 246  * @param fallback the {@link AsyncFunction} to be called if the input fails with the expected 247  * exception type. The function's argument is the input's exception. "The input's exception" 248  * means the cause of the {@link ExecutionException} thrown by {@code input.get()} or, if 249  * {@code get()} throws a different kind of exception, that exception itself. 250  * @param executor the executor that runs {@code fallback} if the input fails 251  */ 252  @Partially.GwtIncompatible("AVAILABLE but requires exceptionType to be Throwable.class") 253  public final <X extends Throwable> FluentFuture<V> catchingAsync( 254  Class<X> exceptionType, AsyncFunction<? super X, ? extends V> fallback, Executor executor) { 255  return (FluentFuture<V>) Futures.catchingAsync(this, exceptionType, fallback, executor); 256  } 257  258  /** 259  * Returns a future that delegates to this future but will finish early (via a {@link 260  * TimeoutException} wrapped in an {@link ExecutionException}) if the specified timeout expires. 261  * If the timeout expires, not only will the output future finish, but also the input future 262  * ({@code this}) will be cancelled and interrupted. 263  * 264  * @param timeout when to time out the future 265  * @param scheduledExecutor The executor service to enforce the timeout. 266  * @since 28.0 267  */ 268  @GwtIncompatible // ScheduledExecutorService 269  public final FluentFuture<V> withTimeout( 270  Duration timeout, ScheduledExecutorService scheduledExecutor) { 271  return withTimeout(toNanosSaturated(timeout), TimeUnit.NANOSECONDS, scheduledExecutor); 272  } 273  274  /** 275  * Returns a future that delegates to this future but will finish early (via a {@link 276  * TimeoutException} wrapped in an {@link ExecutionException}) if the specified timeout expires. 277  * If the timeout expires, not only will the output future finish, but also the input future 278  * ({@code this}) will be cancelled and interrupted. 279  * 280  * @param timeout when to time out the future 281  * @param unit the time unit of the time parameter 282  * @param scheduledExecutor The executor service to enforce the timeout. 283  */ 284  @GwtIncompatible // ScheduledExecutorService 285  @SuppressWarnings("GoodTime") // should accept a java.time.Duration 286  public final FluentFuture<V> withTimeout( 287  long timeout, TimeUnit unit, ScheduledExecutorService scheduledExecutor) { 288  return (FluentFuture<V>) Futures.withTimeout(this, timeout, unit, scheduledExecutor); 289  } 290  291  /** 292  * Returns a new {@code Future} whose result is asynchronously derived from the result of this 293  * {@code Future}. If the input {@code Future} fails, the returned {@code Future} fails with the 294  * same exception (and the function is not invoked). 295  * 296  * <p>More precisely, the returned {@code Future} takes its result from a {@code Future} produced 297  * by applying the given {@code AsyncFunction} to the result of the original {@code Future}. 298  * Example usage: 299  * 300  * <pre>{@code 301  * FluentFuture<RowKey> rowKeyFuture = FluentFuture.from(indexService.lookUp(query)); 302  * ListenableFuture<QueryResult> queryFuture = 303  * rowKeyFuture.transformAsync(dataService::readFuture, executor); 304  * }</pre> 305  * 306  * <p>When selecting an executor, note that {@code directExecutor} is dangerous in some cases. See 307  * the discussion in the {@link #addListener} documentation. All its warnings about heavyweight 308  * listeners are also applicable to heavyweight functions passed to this method. (Specifically, 309  * {@code directExecutor} functions should avoid heavyweight operations inside {@code 310  * AsyncFunction.apply}. Any heavyweight operations should occur in other threads responsible for 311  * completing the returned {@code Future}.) 312  * 313  * <p>The returned {@code Future} attempts to keep its cancellation state in sync with that of the 314  * input future and that of the future returned by the chain function. That is, if the returned 315  * {@code Future} is cancelled, it will attempt to cancel the other two, and if either of the 316  * other two is cancelled, the returned {@code Future} will receive a callback in which it will 317  * attempt to cancel itself. 318  * 319  * <p>This method is similar to {@link java.util.concurrent.CompletableFuture#thenCompose} and 320  * {@link java.util.concurrent.CompletableFuture#thenComposeAsync}. It can also serve some of the 321  * use cases of {@link java.util.concurrent.CompletableFuture#handle} and {@link 322  * java.util.concurrent.CompletableFuture#handleAsync} when used along with {@link #catching}. 323  * 324  * @param function A function to transform the result of this future to the result of the output 325  * future 326  * @param executor Executor to run the function in. 327  * @return A future that holds result of the function (if the input succeeded) or the original 328  * input's failure (if not) 329  */ 330  public final <T extends @Nullable Object> FluentFuture<T> transformAsync( 331  AsyncFunction<? super V, T> function, Executor executor) { 332  return (FluentFuture<T>) Futures.transformAsync(this, function, executor); 333  } 334  335  /** 336  * Returns a new {@code Future} whose result is derived from the result of this {@code Future}. If 337  * this input {@code Future} fails, the returned {@code Future} fails with the same exception (and 338  * the function is not invoked). Example usage: 339  * 340  * <pre>{@code 341  * ListenableFuture<List<Row>> rowsFuture = 342  * queryFuture.transform(QueryResult::getRows, executor); 343  * }</pre> 344  * 345  * <p>When selecting an executor, note that {@code directExecutor} is dangerous in some cases. See 346  * the discussion in the {@link #addListener} documentation. All its warnings about heavyweight 347  * listeners are also applicable to heavyweight functions passed to this method. 348  * 349  * <p>The returned {@code Future} attempts to keep its cancellation state in sync with that of the 350  * input future. That is, if the returned {@code Future} is cancelled, it will attempt to cancel 351  * the input, and if the input is cancelled, the returned {@code Future} will receive a callback 352  * in which it will attempt to cancel itself. 353  * 354  * <p>An example use of this method is to convert a serializable object returned from an RPC into 355  * a POJO. 356  * 357  * <p>This method is similar to {@link java.util.concurrent.CompletableFuture#thenApply} and 358  * {@link java.util.concurrent.CompletableFuture#thenApplyAsync}. It can also serve some of the 359  * use cases of {@link java.util.concurrent.CompletableFuture#handle} and {@link 360  * java.util.concurrent.CompletableFuture#handleAsync} when used along with {@link #catching}. 361  * 362  * @param function A Function to transform the results of this future to the results of the 363  * returned future. 364  * @param executor Executor to run the function in. 365  * @return A future that holds result of the transformation. 366  */ 367  public final <T extends @Nullable Object> FluentFuture<T> transform( 368  Function<? super V, T> function, Executor executor) { 369  return (FluentFuture<T>) Futures.transform(this, function, executor); 370  } 371  372  /** 373  * Registers separate success and failure callbacks to be run when this {@code Future}'s 374  * computation is {@linkplain java.util.concurrent.Future#isDone() complete} or, if the 375  * computation is already complete, immediately. 376  * 377  * <p>The callback is run on {@code executor}. There is no guaranteed ordering of execution of 378  * callbacks, but any callback added through this method is guaranteed to be called once the 379  * computation is complete. 380  * 381  * <p>Example: 382  * 383  * <pre>{@code 384  * future.addCallback( 385  * new FutureCallback<QueryResult>() { 386  * public void onSuccess(QueryResult result) { 387  * storeInCache(result); 388  * } 389  * public void onFailure(Throwable t) { 390  * reportError(t); 391  * } 392  * }, executor); 393  * }</pre> 394  * 395  * <p>When selecting an executor, note that {@code directExecutor} is dangerous in some cases. See 396  * the discussion in the {@link #addListener} documentation. All its warnings about heavyweight 397  * listeners are also applicable to heavyweight callbacks passed to this method. 398  * 399  * <p>For a more general interface to attach a completion listener, see {@link #addListener}. 400  * 401  * <p>This method is similar to {@link java.util.concurrent.CompletableFuture#whenComplete} and 402  * {@link java.util.concurrent.CompletableFuture#whenCompleteAsync}. It also serves the use case 403  * of {@link java.util.concurrent.CompletableFuture#thenAccept} and {@link 404  * java.util.concurrent.CompletableFuture#thenAcceptAsync}. 405  * 406  * @param callback The callback to invoke when this {@code Future} is completed. 407  * @param executor The executor to run {@code callback} when the future completes. 408  */ 409  public final void addCallback(FutureCallback<? super V> callback, Executor executor) { 410  Futures.addCallback(this, callback, executor); 411  } 412 }