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}