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}