001/* 002 * Copyright (C) 2017 The Guava Authors 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package com.google.common.util.concurrent; 018 019import static com.google.common.base.Functions.constant; 020import static com.google.common.base.MoreObjects.toStringHelper; 021import static com.google.common.base.Preconditions.checkArgument; 022import static com.google.common.base.Preconditions.checkNotNull; 023import static com.google.common.base.Preconditions.checkState; 024import static com.google.common.collect.Lists.asList; 025import static com.google.common.util.concurrent.ClosingFuture.State.CLOSED; 026import static com.google.common.util.concurrent.ClosingFuture.State.CLOSING; 027import static com.google.common.util.concurrent.ClosingFuture.State.OPEN; 028import static com.google.common.util.concurrent.ClosingFuture.State.SUBSUMED; 029import static com.google.common.util.concurrent.ClosingFuture.State.WILL_CLOSE; 030import static com.google.common.util.concurrent.ClosingFuture.State.WILL_CREATE_VALUE_AND_CLOSER; 031import static com.google.common.util.concurrent.Futures.getDone; 032import static com.google.common.util.concurrent.Futures.immediateFuture; 033import static com.google.common.util.concurrent.Futures.nonCancellationPropagating; 034import static com.google.common.util.concurrent.MoreExecutors.directExecutor; 035import static com.google.common.util.concurrent.Platform.restoreInterruptIfIsInterruptedException; 036import static java.util.logging.Level.FINER; 037import static java.util.logging.Level.SEVERE; 038import static java.util.logging.Level.WARNING; 039 040import com.google.common.annotations.VisibleForTesting; 041import com.google.common.base.Function; 042import com.google.common.collect.FluentIterable; 043import com.google.common.collect.ImmutableList; 044import com.google.common.util.concurrent.ClosingFuture.Combiner.AsyncCombiningCallable; 045import com.google.common.util.concurrent.ClosingFuture.Combiner.CombiningCallable; 046import com.google.common.util.concurrent.Futures.FutureCombiner; 047import com.google.errorprone.annotations.CanIgnoreReturnValue; 048import com.google.errorprone.annotations.DoNotMock; 049import com.google.j2objc.annotations.RetainedWith; 050import java.io.Closeable; 051import java.util.IdentityHashMap; 052import java.util.Map; 053import java.util.concurrent.Callable; 054import java.util.concurrent.CancellationException; 055import java.util.concurrent.CountDownLatch; 056import java.util.concurrent.ExecutionException; 057import java.util.concurrent.Executor; 058import java.util.concurrent.Future; 059import java.util.concurrent.RejectedExecutionException; 060import java.util.concurrent.atomic.AtomicReference; 061import java.util.logging.Logger; 062import javax.annotation.CheckForNull; 063import org.checkerframework.checker.nullness.qual.Nullable; 064 065/** 066 * A step in a pipeline of an asynchronous computation. When the last step in the computation is 067 * complete, some objects captured during the computation are closed. 068 * 069 * <p>A pipeline of {@code ClosingFuture}s is a tree of steps. Each step represents either an 070 * asynchronously-computed intermediate value, or else an exception that indicates the failure or 071 * cancellation of the operation so far. The only way to extract the value or exception from a step 072 * is by declaring that step to be the last step of the pipeline. Nevertheless, we refer to the 073 * "value" of a successful step or the "result" (value or exception) of any step. 074 * 075 * <ol> 076 * <li>A pipeline starts at its leaf step (or steps), which is created from either a callable 077 * block or a {@link ListenableFuture}. 078 * <li>Each other step is derived from one or more input steps. At each step, zero or more objects 079 * can be captured for later closing. 080 * <li>There is one last step (the root of the tree), from which you can extract the final result 081 * of the computation. After that result is available (or the computation fails), all objects 082 * captured by any of the steps in the pipeline are closed. 083 * </ol> 084 * 085 * <h3>Starting a pipeline</h3> 086 * 087 * Start a {@code ClosingFuture} pipeline {@linkplain #submit(ClosingCallable, Executor) from a 088 * callable block} that may capture objects for later closing. To start a pipeline from a {@link 089 * ListenableFuture} that doesn't create resources that should be closed later, you can use {@link 090 * #from(ListenableFuture)} instead. 091 * 092 * <h3>Derived steps</h3> 093 * 094 * A {@code ClosingFuture} step can be derived from one or more input {@code ClosingFuture} steps in 095 * ways similar to {@link FluentFuture}s: 096 * 097 * <ul> 098 * <li>by transforming the value from a successful input step, 099 * <li>by catching the exception from a failed input step, or 100 * <li>by combining the results of several input steps. 101 * </ul> 102 * 103 * Each derivation can capture the next value or any intermediate objects for later closing. 104 * 105 * <p>A step can be the input to at most one derived step. Once you transform its value, catch its 106 * exception, or combine it with others, you cannot do anything else with it, including declare it 107 * to be the last step of the pipeline. 108 * 109 * <h4>Transforming</h4> 110 * 111 * To derive the next step by asynchronously applying a function to an input step's value, call 112 * {@link #transform(ClosingFunction, Executor)} or {@link #transformAsync(AsyncClosingFunction, 113 * Executor)} on the input step. 114 * 115 * <h4>Catching</h4> 116 * 117 * To derive the next step from a failed input step, call {@link #catching(Class, ClosingFunction, 118 * Executor)} or {@link #catchingAsync(Class, AsyncClosingFunction, Executor)} on the input step. 119 * 120 * <h4>Combining</h4> 121 * 122 * To derive a {@code ClosingFuture} from two or more input steps, pass the input steps to {@link 123 * #whenAllComplete(Iterable)} or {@link #whenAllSucceed(Iterable)} or its overloads. 124 * 125 * <h3>Cancelling</h3> 126 * 127 * Any step in a pipeline can be {@linkplain #cancel(boolean) cancelled}, even after another step 128 * has been derived, with the same semantics as cancelling a {@link Future}. In addition, a 129 * successfully cancelled step will immediately start closing all objects captured for later closing 130 * by it and by its input steps. 131 * 132 * <h3>Ending a pipeline</h3> 133 * 134 * Each {@code ClosingFuture} pipeline must be ended. To end a pipeline, decide whether you want to 135 * close the captured objects automatically or manually. 136 * 137 * <h4>Automatically closing</h4> 138 * 139 * You can extract a {@link Future} that represents the result of the last step in the pipeline by 140 * calling {@link #finishToFuture()}. All objects the pipeline has captured for closing will begin 141 * to be closed asynchronously <b>after</b> the returned {@code Future} is done: the future 142 * completes before closing starts, rather than once it has finished. 143 * 144 * <pre>{@code 145 * FluentFuture<UserName> userName = 146 * ClosingFuture.submit( 147 * closer -> closer.eventuallyClose(database.newTransaction(), closingExecutor), 148 * executor) 149 * .transformAsync((closer, transaction) -> transaction.queryClosingFuture("..."), executor) 150 * .transform((closer, result) -> result.get("userName"), directExecutor()) 151 * .catching(DBException.class, e -> "no user", directExecutor()) 152 * .finishToFuture(); 153 * }</pre> 154 * 155 * In this example, when the {@code userName} {@link Future} is done, the transaction and the query 156 * result cursor will both be closed, even if the operation is cancelled or fails. 157 * 158 * <h4>Manually closing</h4> 159 * 160 * If you want to close the captured objects manually, after you've used the final result, call 161 * {@link #finishToValueAndCloser(ValueAndCloserConsumer, Executor)} to get an object that holds the 162 * final result. You then call {@link ValueAndCloser#closeAsync()} to close the captured objects. 163 * 164 * <pre>{@code 165 * ClosingFuture.submit( 166 * closer -> closer.eventuallyClose(database.newTransaction(), closingExecutor), 167 * executor) 168 * .transformAsync((closer, transaction) -> transaction.queryClosingFuture("..."), executor) 169 * .transform((closer, result) -> result.get("userName"), directExecutor()) 170 * .catching(DBException.class, e -> "no user", directExecutor()) 171 * .finishToValueAndCloser( 172 * valueAndCloser -> this.userNameValueAndCloser = valueAndCloser, executor); 173 * 174 * // later 175 * try { // get() will throw if the operation failed or was cancelled. 176 * UserName userName = userNameValueAndCloser.get(); 177 * // do something with userName 178 * } finally { 179 * userNameValueAndCloser.closeAsync(); 180 * } 181 * }</pre> 182 * 183 * In this example, when {@code userNameValueAndCloser.closeAsync()} is called, the transaction and 184 * the query result cursor will both be closed, even if the operation is cancelled or fails. 185 * 186 * <p>Note that if you don't call {@code closeAsync()}, the captured objects will not be closed. The 187 * automatic-closing approach described above is safer. 188 * 189 * @param <V> the type of the value of this step 190 * @since 30.0 191 */ 192// TODO(dpb): Consider reusing one CloseableList for the entire pipeline, modulo combinations. 193@DoNotMock("Use ClosingFuture.from(Futures.immediate*Future)") 194@ElementTypesAreNonnullByDefault 195// TODO(dpb): GWT compatibility. 196public final class ClosingFuture<V extends @Nullable Object> { 197 198 private static final Logger logger = Logger.getLogger(ClosingFuture.class.getName()); 199 200 /** 201 * An object that can capture objects to be closed later, when a {@link ClosingFuture} pipeline is 202 * done. 203 */ 204 public static final class DeferredCloser { 205 @RetainedWith private final CloseableList list; 206 207 DeferredCloser(CloseableList list) { 208 this.list = list; 209 } 210 211 /** 212 * Captures an object to be closed when a {@link ClosingFuture} pipeline is done. 213 * 214 * <p>For users of the {@code -jre} flavor of Guava, the object can be any {@code 215 * AutoCloseable}. For users of the {@code -android} flavor, the object must be a {@code 216 * Closeable}. (For more about the flavors, see <a 217 * href="https://github.com/google/guava#adding-guava-to-your-build">Adding Guava to your 218 * build</a>.) 219 * 220 * <p>Be careful when targeting an older SDK than you are building against (most commonly when 221 * building for Android): Ensure that any object you pass implements the interface not just in 222 * your current SDK version but also at the oldest version you support. For example, <a 223 * href="https://developer.android.com/sdk/api_diff/16/">API Level 16</a> is the first version 224 * in which {@code Cursor} is {@code Closeable}. To support older versions, pass a wrapper 225 * {@code Closeable} with a method reference like {@code cursor::close}. 226 * 227 * <p>Note that this method is still binary-compatible between flavors because the erasure of 228 * its parameter type is {@code Object}, not {@code AutoCloseable} or {@code Closeable}. 229 * 230 * @param closeable the object to be closed (see notes above) 231 * @param closingExecutor the object will be closed on this executor 232 * @return the first argument 233 */ 234 @CanIgnoreReturnValue 235 @ParametricNullness 236 public <C extends @Nullable Object & @Nullable AutoCloseable> C eventuallyClose( 237 @ParametricNullness C closeable, Executor closingExecutor) { 238 checkNotNull(closingExecutor); 239 if (closeable != null) { 240 list.add(closeable, closingExecutor); 241 } 242 return closeable; 243 } 244 } 245 246 /** 247 * An operation that computes a result. 248 * 249 * @param <V> the type of the result 250 */ 251 @FunctionalInterface 252 public interface ClosingCallable<V extends @Nullable Object> { 253 /** 254 * Computes a result, or throws an exception if unable to do so. 255 * 256 * <p>Any objects that are passed to {@link DeferredCloser#eventuallyClose(Closeable, Executor) 257 * closer.eventuallyClose()} will be closed when the {@link ClosingFuture} pipeline is done (but 258 * not before this method completes), even if this method throws or the pipeline is cancelled. 259 */ 260 @ParametricNullness 261 V call(DeferredCloser closer) throws Exception; 262 } 263 264 /** 265 * An operation that computes a {@link ClosingFuture} of a result. 266 * 267 * @param <V> the type of the result 268 * @since 30.1 269 */ 270 @FunctionalInterface 271 public interface AsyncClosingCallable<V extends @Nullable Object> { 272 /** 273 * Computes a result, or throws an exception if unable to do so. 274 * 275 * <p>Any objects that are passed to {@link DeferredCloser#eventuallyClose(Closeable, Executor) 276 * closer.eventuallyClose()} will be closed when the {@link ClosingFuture} pipeline is done (but 277 * not before this method completes), even if this method throws or the pipeline is cancelled. 278 */ 279 ClosingFuture<V> call(DeferredCloser closer) throws Exception; 280 } 281 282 /** 283 * A function from an input to a result. 284 * 285 * @param <T> the type of the input to the function 286 * @param <U> the type of the result of the function 287 */ 288 @FunctionalInterface 289 public interface ClosingFunction<T extends @Nullable Object, U extends @Nullable Object> { 290 291 /** 292 * Applies this function to an input, or throws an exception if unable to do so. 293 * 294 * <p>Any objects that are passed to {@link DeferredCloser#eventuallyClose(Closeable, Executor) 295 * closer.eventuallyClose()} will be closed when the {@link ClosingFuture} pipeline is done (but 296 * not before this method completes), even if this method throws or the pipeline is cancelled. 297 */ 298 @ParametricNullness 299 U apply(DeferredCloser closer, @ParametricNullness T input) throws Exception; 300 } 301 302 /** 303 * A function from an input to a {@link ClosingFuture} of a result. 304 * 305 * @param <T> the type of the input to the function 306 * @param <U> the type of the result of the function 307 */ 308 @FunctionalInterface 309 public interface AsyncClosingFunction<T extends @Nullable Object, U extends @Nullable Object> { 310 /** 311 * Applies this function to an input, or throws an exception if unable to do so. 312 * 313 * <p>Any objects that are passed to {@link DeferredCloser#eventuallyClose(Closeable, Executor) 314 * closer.eventuallyClose()} will be closed when the {@link ClosingFuture} pipeline is done (but 315 * not before this method completes), even if this method throws or the pipeline is cancelled. 316 */ 317 ClosingFuture<U> apply(DeferredCloser closer, @ParametricNullness T input) throws Exception; 318 } 319 320 /** 321 * An object that holds the final result of an asynchronous {@link ClosingFuture} operation and 322 * allows the user to close all the closeable objects that were captured during it for later 323 * closing. 324 * 325 * <p>The asynchronous operation will have completed before this object is created. 326 * 327 * @param <V> the type of the value of a successful operation 328 * @see ClosingFuture#finishToValueAndCloser(ValueAndCloserConsumer, Executor) 329 */ 330 public static final class ValueAndCloser<V extends @Nullable Object> { 331 332 private final ClosingFuture<? extends V> closingFuture; 333 334 ValueAndCloser(ClosingFuture<? extends V> closingFuture) { 335 this.closingFuture = checkNotNull(closingFuture); 336 } 337 338 /** 339 * Returns the final value of the associated {@link ClosingFuture}, or throws an exception as 340 * {@link Future#get()} would. 341 * 342 * <p>Because the asynchronous operation has already completed, this method is synchronous and 343 * returns immediately. 344 * 345 * @throws CancellationException if the computation was cancelled 346 * @throws ExecutionException if the computation threw an exception 347 */ 348 @ParametricNullness 349 public V get() throws ExecutionException { 350 return getDone(closingFuture.future); 351 } 352 353 /** 354 * Starts closing all closeable objects captured during the {@link ClosingFuture}'s asynchronous 355 * operation on the {@link Executor}s specified by calls to {@link 356 * DeferredCloser#eventuallyClose(Closeable, Executor)}. 357 * 358 * <p>If any such calls specified {@link MoreExecutors#directExecutor()}, those objects will be 359 * closed synchronously. 360 * 361 * <p>Idempotent: objects will be closed at most once. 362 */ 363 public void closeAsync() { 364 closingFuture.close(); 365 } 366 } 367 368 /** 369 * Represents an operation that accepts a {@link ValueAndCloser} for the last step in a {@link 370 * ClosingFuture} pipeline. 371 * 372 * @param <V> the type of the final value of a successful pipeline 373 * @see ClosingFuture#finishToValueAndCloser(ValueAndCloserConsumer, Executor) 374 */ 375 @FunctionalInterface 376 public interface ValueAndCloserConsumer<V extends @Nullable Object> { 377 378 /** Accepts a {@link ValueAndCloser} for the last step in a {@link ClosingFuture} pipeline. */ 379 void accept(ValueAndCloser<V> valueAndCloser); 380 } 381 382 /** 383 * Starts a {@link ClosingFuture} pipeline by submitting a callable block to an executor. 384 * 385 * @throws java.util.concurrent.RejectedExecutionException if the task cannot be scheduled for 386 * execution 387 */ 388 public static <V extends @Nullable Object> ClosingFuture<V> submit( 389 ClosingCallable<V> callable, Executor executor) { 390 return new ClosingFuture<>(callable, executor); 391 } 392 393 /** 394 * Starts a {@link ClosingFuture} pipeline by submitting a callable block to an executor. 395 * 396 * @throws java.util.concurrent.RejectedExecutionException if the task cannot be scheduled for 397 * execution 398 * @since 30.1 399 */ 400 public static <V extends @Nullable Object> ClosingFuture<V> submitAsync( 401 AsyncClosingCallable<V> callable, Executor executor) { 402 return new ClosingFuture<>(callable, executor); 403 } 404 405 /** 406 * Starts a {@link ClosingFuture} pipeline with a {@link ListenableFuture}. 407 * 408 * <p>{@code future}'s value will not be closed when the pipeline is done even if {@code V} 409 * implements {@link Closeable}. In order to start a pipeline with a value that will be closed 410 * when the pipeline is done, use {@link #submit(ClosingCallable, Executor)} instead. 411 */ 412 public static <V extends @Nullable Object> ClosingFuture<V> from(ListenableFuture<V> future) { 413 return new ClosingFuture<V>(future); 414 } 415 416 /** 417 * Starts a {@link ClosingFuture} pipeline with a {@link ListenableFuture}. 418 * 419 * <p>If {@code future} succeeds, its value will be closed (using {@code closingExecutor)} when 420 * the pipeline is done, even if the pipeline is canceled or fails. 421 * 422 * <p>Cancelling the pipeline will not cancel {@code future}, so that the pipeline can access its 423 * value in order to close it. 424 * 425 * @param future the future to create the {@code ClosingFuture} from. For discussion of the 426 * future's result type {@code C}, see {@link DeferredCloser#eventuallyClose(Closeable, 427 * Executor)}. 428 * @param closingExecutor the future's result will be closed on this executor 429 * @deprecated Creating {@link Future}s of closeable types is dangerous in general because the 430 * underlying value may never be closed if the {@link Future} is canceled after its operation 431 * begins. Consider replacing code that creates {@link ListenableFuture}s of closeable types, 432 * including those that pass them to this method, with {@link #submit(ClosingCallable, 433 * Executor)} in order to ensure that resources do not leak. Or, to start a pipeline with a 434 * {@link ListenableFuture} that doesn't create values that should be closed, use {@link 435 * ClosingFuture#from}. 436 */ 437 @Deprecated 438 public static <C extends @Nullable Object & @Nullable AutoCloseable> 439 ClosingFuture<C> eventuallyClosing( 440 ListenableFuture<C> future, final Executor closingExecutor) { 441 checkNotNull(closingExecutor); 442 final ClosingFuture<C> closingFuture = new ClosingFuture<>(nonCancellationPropagating(future)); 443 Futures.addCallback( 444 future, 445 new FutureCallback<@Nullable AutoCloseable>() { 446 @Override 447 public void onSuccess(@CheckForNull AutoCloseable result) { 448 closingFuture.closeables.closer.eventuallyClose(result, closingExecutor); 449 } 450 451 @Override 452 public void onFailure(Throwable t) {} 453 }, 454 directExecutor()); 455 return closingFuture; 456 } 457 458 /** 459 * Starts specifying how to combine {@link ClosingFuture}s into a single pipeline. 460 * 461 * @throws IllegalStateException if a {@code ClosingFuture} has already been derived from any of 462 * the {@code futures}, or if any has already been {@linkplain #finishToFuture() finished} 463 */ 464 public static Combiner whenAllComplete(Iterable<? extends ClosingFuture<?>> futures) { 465 return new Combiner(false, futures); 466 } 467 468 /** 469 * Starts specifying how to combine {@link ClosingFuture}s into a single pipeline. 470 * 471 * @throws IllegalStateException if a {@code ClosingFuture} has already been derived from any of 472 * the arguments, or if any has already been {@linkplain #finishToFuture() finished} 473 */ 474 public static Combiner whenAllComplete( 475 ClosingFuture<?> future1, ClosingFuture<?>... moreFutures) { 476 return whenAllComplete(asList(future1, moreFutures)); 477 } 478 479 /** 480 * Starts specifying how to combine {@link ClosingFuture}s into a single pipeline, assuming they 481 * all succeed. If any fail, the resulting pipeline will fail. 482 * 483 * @throws IllegalStateException if a {@code ClosingFuture} has already been derived from any of 484 * the {@code futures}, or if any has already been {@linkplain #finishToFuture() finished} 485 */ 486 public static Combiner whenAllSucceed(Iterable<? extends ClosingFuture<?>> futures) { 487 return new Combiner(true, futures); 488 } 489 490 /** 491 * Starts specifying how to combine two {@link ClosingFuture}s into a single pipeline, assuming 492 * they all succeed. If any fail, the resulting pipeline will fail. 493 * 494 * <p>Calling this method allows you to use lambdas or method references typed with the types of 495 * the input {@link ClosingFuture}s. 496 * 497 * @throws IllegalStateException if a {@code ClosingFuture} has already been derived from any of 498 * the arguments, or if any has already been {@linkplain #finishToFuture() finished} 499 */ 500 public static <V1 extends @Nullable Object, V2 extends @Nullable Object> 501 Combiner2<V1, V2> whenAllSucceed(ClosingFuture<V1> future1, ClosingFuture<V2> future2) { 502 return new Combiner2<>(future1, future2); 503 } 504 505 /** 506 * Starts specifying how to combine three {@link ClosingFuture}s into a single pipeline, assuming 507 * they all succeed. If any fail, the resulting pipeline will fail. 508 * 509 * <p>Calling this method allows you to use lambdas or method references typed with the types of 510 * the input {@link ClosingFuture}s. 511 * 512 * @throws IllegalStateException if a {@code ClosingFuture} has already been derived from any of 513 * the arguments, or if any has already been {@linkplain #finishToFuture() finished} 514 */ 515 public static < 516 V1 extends @Nullable Object, V2 extends @Nullable Object, V3 extends @Nullable Object> 517 Combiner3<V1, V2, V3> whenAllSucceed( 518 ClosingFuture<V1> future1, ClosingFuture<V2> future2, ClosingFuture<V3> future3) { 519 return new Combiner3<>(future1, future2, future3); 520 } 521 522 /** 523 * Starts specifying how to combine four {@link ClosingFuture}s into a single pipeline, assuming 524 * they all succeed. If any fail, the resulting pipeline will fail. 525 * 526 * <p>Calling this method allows you to use lambdas or method references typed with the types of 527 * the input {@link ClosingFuture}s. 528 * 529 * @throws IllegalStateException if a {@code ClosingFuture} has already been derived from any of 530 * the arguments, or if any has already been {@linkplain #finishToFuture() finished} 531 */ 532 public static < 533 V1 extends @Nullable Object, 534 V2 extends @Nullable Object, 535 V3 extends @Nullable Object, 536 V4 extends @Nullable Object> 537 Combiner4<V1, V2, V3, V4> whenAllSucceed( 538 ClosingFuture<V1> future1, 539 ClosingFuture<V2> future2, 540 ClosingFuture<V3> future3, 541 ClosingFuture<V4> future4) { 542 return new Combiner4<>(future1, future2, future3, future4); 543 } 544 545 /** 546 * Starts specifying how to combine five {@link ClosingFuture}s into a single pipeline, assuming 547 * they all succeed. If any fail, the resulting pipeline will fail. 548 * 549 * <p>Calling this method allows you to use lambdas or method references typed with the types of 550 * the input {@link ClosingFuture}s. 551 * 552 * @throws IllegalStateException if a {@code ClosingFuture} has already been derived from any of 553 * the arguments, or if any has already been {@linkplain #finishToFuture() finished} 554 */ 555 public static < 556 V1 extends @Nullable Object, 557 V2 extends @Nullable Object, 558 V3 extends @Nullable Object, 559 V4 extends @Nullable Object, 560 V5 extends @Nullable Object> 561 Combiner5<V1, V2, V3, V4, V5> whenAllSucceed( 562 ClosingFuture<V1> future1, 563 ClosingFuture<V2> future2, 564 ClosingFuture<V3> future3, 565 ClosingFuture<V4> future4, 566 ClosingFuture<V5> future5) { 567 return new Combiner5<>(future1, future2, future3, future4, future5); 568 } 569 570 /** 571 * Starts specifying how to combine {@link ClosingFuture}s into a single pipeline, assuming they 572 * all succeed. If any fail, the resulting pipeline will fail. 573 * 574 * @throws IllegalStateException if a {@code ClosingFuture} has already been derived from any of 575 * the arguments, or if any has already been {@linkplain #finishToFuture() finished} 576 */ 577 public static Combiner whenAllSucceed( 578 ClosingFuture<?> future1, 579 ClosingFuture<?> future2, 580 ClosingFuture<?> future3, 581 ClosingFuture<?> future4, 582 ClosingFuture<?> future5, 583 ClosingFuture<?> future6, 584 ClosingFuture<?>... moreFutures) { 585 return whenAllSucceed( 586 FluentIterable.of(future1, future2, future3, future4, future5, future6) 587 .append(moreFutures)); 588 } 589 590 private final AtomicReference<State> state = new AtomicReference<>(OPEN); 591 private final CloseableList closeables = new CloseableList(); 592 private final FluentFuture<V> future; 593 594 private ClosingFuture(ListenableFuture<V> future) { 595 this.future = FluentFuture.from(future); 596 } 597 598 private ClosingFuture(final ClosingCallable<V> callable, Executor executor) { 599 checkNotNull(callable); 600 TrustedListenableFutureTask<V> task = 601 TrustedListenableFutureTask.create( 602 new Callable<V>() { 603 @Override 604 @ParametricNullness 605 public V call() throws Exception { 606 return callable.call(closeables.closer); 607 } 608 609 @Override 610 public String toString() { 611 return callable.toString(); 612 } 613 }); 614 executor.execute(task); 615 this.future = task; 616 } 617 618 private ClosingFuture(final AsyncClosingCallable<V> callable, Executor executor) { 619 checkNotNull(callable); 620 TrustedListenableFutureTask<V> task = 621 TrustedListenableFutureTask.create( 622 new AsyncCallable<V>() { 623 @Override 624 public ListenableFuture<V> call() throws Exception { 625 CloseableList newCloseables = new CloseableList(); 626 try { 627 ClosingFuture<V> closingFuture = callable.call(newCloseables.closer); 628 closingFuture.becomeSubsumedInto(closeables); 629 return closingFuture.future; 630 } finally { 631 closeables.add(newCloseables, directExecutor()); 632 } 633 } 634 635 @Override 636 public String toString() { 637 return callable.toString(); 638 } 639 }); 640 executor.execute(task); 641 this.future = task; 642 } 643 644 /** 645 * Returns a future that finishes when this step does. Calling {@code get()} on the returned 646 * future returns {@code null} if the step is successful or throws the same exception that would 647 * be thrown by calling {@code finishToFuture().get()} if this were the last step. Calling {@code 648 * cancel()} on the returned future has no effect on the {@code ClosingFuture} pipeline. 649 * 650 * <p>{@code statusFuture} differs from most methods on {@code ClosingFuture}: You can make calls 651 * to {@code statusFuture} <i>in addition to</i> the call you make to {@link #finishToFuture()} or 652 * a derivation method <i>on the same instance</i>. This is important because calling {@code 653 * statusFuture} alone does not provide a way to close the pipeline. 654 */ 655 public ListenableFuture<?> statusFuture() { 656 return nonCancellationPropagating(future.transform(constant(null), directExecutor())); 657 } 658 659 /** 660 * Returns a new {@code ClosingFuture} pipeline step derived from this one by applying a function 661 * to its value. The function can use a {@link DeferredCloser} to capture objects to be closed 662 * when the pipeline is done. 663 * 664 * <p>If this {@code ClosingFuture} fails, the function will not be called, and the derived {@code 665 * ClosingFuture} will be equivalent to this one. 666 * 667 * <p>If the function throws an exception, that exception is used as the result of the derived 668 * {@code ClosingFuture}. 669 * 670 * <p>Example usage: 671 * 672 * <pre>{@code 673 * ClosingFuture<List<Row>> rowsFuture = 674 * queryFuture.transform((closer, result) -> result.getRows(), executor); 675 * }</pre> 676 * 677 * <p>When selecting an executor, note that {@code directExecutor} is dangerous in some cases. See 678 * the discussion in the {@link ListenableFuture#addListener} documentation. All its warnings 679 * about heavyweight listeners are also applicable to heavyweight functions passed to this method. 680 * 681 * <p>After calling this method, you may not call {@link #finishToFuture()}, {@link 682 * #finishToValueAndCloser(ValueAndCloserConsumer, Executor)}, or any other derivation method on 683 * this {@code ClosingFuture}. 684 * 685 * @param function transforms the value of this step to the value of the derived step 686 * @param executor executor to run the function in 687 * @return the derived step 688 * @throws IllegalStateException if a {@code ClosingFuture} has already been derived from this 689 * one, or if this {@code ClosingFuture} has already been {@linkplain #finishToFuture() 690 * finished} 691 */ 692 public <U extends @Nullable Object> ClosingFuture<U> transform( 693 final ClosingFunction<? super V, U> function, Executor executor) { 694 checkNotNull(function); 695 AsyncFunction<V, U> applyFunction = 696 new AsyncFunction<V, U>() { 697 @Override 698 public ListenableFuture<U> apply(V input) throws Exception { 699 return closeables.applyClosingFunction(function, input); 700 } 701 702 @Override 703 public String toString() { 704 return function.toString(); 705 } 706 }; 707 // TODO(dpb): Switch to future.transformSync when that exists (passing a throwing function). 708 return derive(future.transformAsync(applyFunction, executor)); 709 } 710 711 /** 712 * Returns a new {@code ClosingFuture} pipeline step derived from this one by applying a function 713 * that returns a {@code ClosingFuture} to its value. The function can use a {@link 714 * DeferredCloser} to capture objects to be closed when the pipeline is done (other than those 715 * captured by the returned {@link ClosingFuture}). 716 * 717 * <p>If this {@code ClosingFuture} succeeds, the derived one will be equivalent to the one 718 * returned by the function. 719 * 720 * <p>If this {@code ClosingFuture} fails, the function will not be called, and the derived {@code 721 * ClosingFuture} will be equivalent to this one. 722 * 723 * <p>If the function throws an exception, that exception is used as the result of the derived 724 * {@code ClosingFuture}. But if the exception is thrown after the function creates a {@code 725 * ClosingFuture}, then none of the closeable objects in that {@code ClosingFuture} will be 726 * closed. 727 * 728 * <p>Usage guidelines for this method: 729 * 730 * <ul> 731 * <li>Use this method only when calling an API that returns a {@link ListenableFuture} or a 732 * {@code ClosingFuture}. If possible, prefer calling {@link #transform(ClosingFunction, 733 * Executor)} instead, with a function that returns the next value directly. 734 * <li>Call {@link DeferredCloser#eventuallyClose(Closeable, Executor) closer.eventuallyClose()} 735 * for every closeable object this step creates in order to capture it for later closing. 736 * <li>Return a {@code ClosingFuture}. To turn a {@link ListenableFuture} into a {@code 737 * ClosingFuture} call {@link #from(ListenableFuture)}. 738 * <li>In case this step doesn't create new closeables, you can adapt an API that returns a 739 * {@link ListenableFuture} to return a {@code ClosingFuture} by wrapping it with a call to 740 * {@link #withoutCloser(AsyncFunction)} 741 * </ul> 742 * 743 * <p>Example usage: 744 * 745 * <pre>{@code 746 * // Result.getRowsClosingFuture() returns a ClosingFuture. 747 * ClosingFuture<List<Row>> rowsFuture = 748 * queryFuture.transformAsync((closer, result) -> result.getRowsClosingFuture(), executor); 749 * 750 * // Result.writeRowsToOutputStreamFuture() returns a ListenableFuture that resolves to the 751 * // number of written rows. openOutputFile() returns a FileOutputStream (which implements 752 * // Closeable). 753 * ClosingFuture<Integer> rowsFuture2 = 754 * queryFuture.transformAsync( 755 * (closer, result) -> { 756 * FileOutputStream fos = closer.eventuallyClose(openOutputFile(), closingExecutor); 757 * return ClosingFuture.from(result.writeRowsToOutputStreamFuture(fos)); 758 * }, 759 * executor); 760 * 761 * // Result.getRowsFuture() returns a ListenableFuture (no new closeables are created). 762 * ClosingFuture<List<Row>> rowsFuture3 = 763 * queryFuture.transformAsync(withoutCloser(Result::getRowsFuture), executor); 764 * 765 * }</pre> 766 * 767 * <p>When selecting an executor, note that {@code directExecutor} is dangerous in some cases. See 768 * the discussion in the {@link ListenableFuture#addListener} documentation. All its warnings 769 * about heavyweight listeners are also applicable to heavyweight functions passed to this method. 770 * (Specifically, {@code directExecutor} functions should avoid heavyweight operations inside 771 * {@code AsyncClosingFunction.apply}. Any heavyweight operations should occur in other threads 772 * responsible for completing the returned {@code ClosingFuture}.) 773 * 774 * <p>After calling this method, you may not call {@link #finishToFuture()}, {@link 775 * #finishToValueAndCloser(ValueAndCloserConsumer, Executor)}, or any other derivation method on 776 * this {@code ClosingFuture}. 777 * 778 * @param function transforms the value of this step to a {@code ClosingFuture} with the value of 779 * the derived step 780 * @param executor executor to run the function in 781 * @return the derived step 782 * @throws IllegalStateException if a {@code ClosingFuture} has already been derived from this 783 * one, or if this {@code ClosingFuture} has already been {@linkplain #finishToFuture() 784 * finished} 785 */ 786 public <U extends @Nullable Object> ClosingFuture<U> transformAsync( 787 final AsyncClosingFunction<? super V, U> function, Executor executor) { 788 checkNotNull(function); 789 AsyncFunction<V, U> applyFunction = 790 new AsyncFunction<V, U>() { 791 @Override 792 public ListenableFuture<U> apply(V input) throws Exception { 793 return closeables.applyAsyncClosingFunction(function, input); 794 } 795 796 @Override 797 public String toString() { 798 return function.toString(); 799 } 800 }; 801 return derive(future.transformAsync(applyFunction, executor)); 802 } 803 804 /** 805 * Returns an {@link AsyncClosingFunction} that applies an {@link AsyncFunction} to an input, 806 * ignoring the DeferredCloser and returning a {@code ClosingFuture} derived from the returned 807 * {@link ListenableFuture}. 808 * 809 * <p>Use this method to pass a transformation to {@link #transformAsync(AsyncClosingFunction, 810 * Executor)} or to {@link #catchingAsync(Class, AsyncClosingFunction, Executor)} as long as it 811 * meets these conditions: 812 * 813 * <ul> 814 * <li>It does not need to capture any {@link Closeable} objects by calling {@link 815 * DeferredCloser#eventuallyClose(Closeable, Executor)}. 816 * <li>It returns a {@link ListenableFuture}. 817 * </ul> 818 * 819 * <p>Example usage: 820 * 821 * <pre>{@code 822 * // Result.getRowsFuture() returns a ListenableFuture. 823 * ClosingFuture<List<Row>> rowsFuture = 824 * queryFuture.transformAsync(withoutCloser(Result::getRowsFuture), executor); 825 * }</pre> 826 * 827 * @param function transforms the value of a {@code ClosingFuture} step to a {@link 828 * ListenableFuture} with the value of a derived step 829 */ 830 public static <V extends @Nullable Object, U extends @Nullable Object> 831 AsyncClosingFunction<V, U> withoutCloser(final AsyncFunction<V, U> function) { 832 checkNotNull(function); 833 return new AsyncClosingFunction<V, U>() { 834 @Override 835 public ClosingFuture<U> apply(DeferredCloser closer, V input) throws Exception { 836 return ClosingFuture.from(function.apply(input)); 837 } 838 }; 839 } 840 841 /** 842 * Returns a new {@code ClosingFuture} pipeline step derived from this one by applying a function 843 * to its exception if it is an instance of a given exception type. The function can use a {@link 844 * DeferredCloser} to capture objects to be closed when the pipeline is done. 845 * 846 * <p>If this {@code ClosingFuture} succeeds or fails with a different exception type, the 847 * function will not be called, and the derived {@code ClosingFuture} will be equivalent to this 848 * one. 849 * 850 * <p>If the function throws an exception, that exception is used as the result of the derived 851 * {@code ClosingFuture}. 852 * 853 * <p>Example usage: 854 * 855 * <pre>{@code 856 * ClosingFuture<QueryResult> queryFuture = 857 * queryFuture.catching( 858 * QueryException.class, (closer, x) -> Query.emptyQueryResult(), executor); 859 * }</pre> 860 * 861 * <p>When selecting an executor, note that {@code directExecutor} is dangerous in some cases. See 862 * the discussion in the {@link ListenableFuture#addListener} documentation. All its warnings 863 * about heavyweight listeners are also applicable to heavyweight functions passed to this method. 864 * 865 * <p>After calling this method, you may not call {@link #finishToFuture()}, {@link 866 * #finishToValueAndCloser(ValueAndCloserConsumer, Executor)}, or any other derivation method on 867 * this {@code ClosingFuture}. 868 * 869 * @param exceptionType the exception type that triggers use of {@code fallback}. The exception 870 * type is matched against this step's exception. "This step's exception" means the cause of 871 * the {@link ExecutionException} thrown by {@link Future#get()} on the {@link Future} 872 * underlying this step or, if {@code get()} throws a different kind of exception, that 873 * exception itself. To avoid hiding bugs and other unrecoverable errors, callers should 874 * prefer more specific types, avoiding {@code Throwable.class} in particular. 875 * @param fallback the function to be called if this step fails with the expected exception type. 876 * The function's argument is this step's exception. "This step's exception" means the cause 877 * of the {@link ExecutionException} thrown by {@link Future#get()} on the {@link Future} 878 * underlying this step or, if {@code get()} throws a different kind of exception, that 879 * exception itself. 880 * @param executor the executor that runs {@code fallback} if the input fails 881 */ 882 public <X extends Throwable> ClosingFuture<V> catching( 883 Class<X> exceptionType, ClosingFunction<? super X, ? extends V> fallback, Executor executor) { 884 return catchingMoreGeneric(exceptionType, fallback, executor); 885 } 886 887 // Avoids generic type capture inconsistency problems where |? extends V| is incompatible with V. 888 private <X extends Throwable, W extends V> ClosingFuture<V> catchingMoreGeneric( 889 Class<X> exceptionType, final ClosingFunction<? super X, W> fallback, Executor executor) { 890 checkNotNull(fallback); 891 AsyncFunction<X, W> applyFallback = 892 new AsyncFunction<X, W>() { 893 @Override 894 public ListenableFuture<W> apply(X exception) throws Exception { 895 return closeables.applyClosingFunction(fallback, exception); 896 } 897 898 @Override 899 public String toString() { 900 return fallback.toString(); 901 } 902 }; 903 // TODO(dpb): Switch to future.catchingSync when that exists (passing a throwing function). 904 return derive(future.catchingAsync(exceptionType, applyFallback, executor)); 905 } 906 907 /** 908 * Returns a new {@code ClosingFuture} pipeline step derived from this one by applying a function 909 * that returns a {@code ClosingFuture} to its exception if it is an instance of a given exception 910 * type. The function can use a {@link DeferredCloser} to capture objects to be closed when the 911 * pipeline is done (other than those captured by the returned {@link ClosingFuture}). 912 * 913 * <p>If this {@code ClosingFuture} fails with an exception of the given type, the derived {@code 914 * ClosingFuture} will be equivalent to the one returned by the function. 915 * 916 * <p>If this {@code ClosingFuture} succeeds or fails with a different exception type, the 917 * function will not be called, and the derived {@code ClosingFuture} will be equivalent to this 918 * one. 919 * 920 * <p>If the function throws an exception, that exception is used as the result of the derived 921 * {@code ClosingFuture}. But if the exception is thrown after the function creates a {@code 922 * ClosingFuture}, then none of the closeable objects in that {@code ClosingFuture} will be 923 * closed. 924 * 925 * <p>Usage guidelines for this method: 926 * 927 * <ul> 928 * <li>Use this method only when calling an API that returns a {@link ListenableFuture} or a 929 * {@code ClosingFuture}. If possible, prefer calling {@link #catching(Class, 930 * ClosingFunction, Executor)} instead, with a function that returns the next value 931 * directly. 932 * <li>Call {@link DeferredCloser#eventuallyClose(Closeable, Executor) closer.eventuallyClose()} 933 * for every closeable object this step creates in order to capture it for later closing. 934 * <li>Return a {@code ClosingFuture}. To turn a {@link ListenableFuture} into a {@code 935 * ClosingFuture} call {@link #from(ListenableFuture)}. 936 * <li>In case this step doesn't create new closeables, you can adapt an API that returns a 937 * {@link ListenableFuture} to return a {@code ClosingFuture} by wrapping it with a call to 938 * {@link #withoutCloser(AsyncFunction)} 939 * </ul> 940 * 941 * <p>Example usage: 942 * 943 * <pre>{@code 944 * // Fall back to a secondary input stream in case of IOException. 945 * ClosingFuture<InputStream> inputFuture = 946 * firstInputFuture.catchingAsync( 947 * IOException.class, (closer, x) -> secondaryInputStreamClosingFuture(), executor); 948 * } 949 * }</pre> 950 * 951 * <p>When selecting an executor, note that {@code directExecutor} is dangerous in some cases. See 952 * the discussion in the {@link ListenableFuture#addListener} documentation. All its warnings 953 * about heavyweight listeners are also applicable to heavyweight functions passed to this method. 954 * (Specifically, {@code directExecutor} functions should avoid heavyweight operations inside 955 * {@code AsyncClosingFunction.apply}. Any heavyweight operations should occur in other threads 956 * responsible for completing the returned {@code ClosingFuture}.) 957 * 958 * <p>After calling this method, you may not call {@link #finishToFuture()}, {@link 959 * #finishToValueAndCloser(ValueAndCloserConsumer, Executor)}, or any other derivation method on 960 * this {@code ClosingFuture}. 961 * 962 * @param exceptionType the exception type that triggers use of {@code fallback}. The exception 963 * type is matched against this step's exception. "This step's exception" means the cause of 964 * the {@link ExecutionException} thrown by {@link Future#get()} on the {@link Future} 965 * underlying this step or, if {@code get()} throws a different kind of exception, that 966 * exception itself. To avoid hiding bugs and other unrecoverable errors, callers should 967 * prefer more specific types, avoiding {@code Throwable.class} in particular. 968 * @param fallback the function to be called if this step fails with the expected exception type. 969 * The function's argument is this step's exception. "This step's exception" means the cause 970 * of the {@link ExecutionException} thrown by {@link Future#get()} on the {@link Future} 971 * underlying this step or, if {@code get()} throws a different kind of exception, that 972 * exception itself. 973 * @param executor the executor that runs {@code fallback} if the input fails 974 */ 975 // TODO(dpb): Should this do something special if the function throws CancellationException or 976 // ExecutionException? 977 public <X extends Throwable> ClosingFuture<V> catchingAsync( 978 Class<X> exceptionType, 979 AsyncClosingFunction<? super X, ? extends V> fallback, 980 Executor executor) { 981 return catchingAsyncMoreGeneric(exceptionType, fallback, executor); 982 } 983 984 // Avoids generic type capture inconsistency problems where |? extends V| is incompatible with V. 985 private <X extends Throwable, W extends V> ClosingFuture<V> catchingAsyncMoreGeneric( 986 Class<X> exceptionType, 987 final AsyncClosingFunction<? super X, W> fallback, 988 Executor executor) { 989 checkNotNull(fallback); 990 AsyncFunction<X, W> asyncFunction = 991 new AsyncFunction<X, W>() { 992 @Override 993 public ListenableFuture<W> apply(X exception) throws Exception { 994 return closeables.applyAsyncClosingFunction(fallback, exception); 995 } 996 997 @Override 998 public String toString() { 999 return fallback.toString(); 1000 } 1001 }; 1002 return derive(future.catchingAsync(exceptionType, asyncFunction, executor)); 1003 } 1004 1005 /** 1006 * Marks this step as the last step in the {@code ClosingFuture} pipeline. 1007 * 1008 * <p>The returned {@link Future} is completed when the pipeline's computation completes, or when 1009 * the pipeline is cancelled. 1010 * 1011 * <p>All objects the pipeline has captured for closing will begin to be closed asynchronously 1012 * <b>after</b> the returned {@code Future} is done: the future completes before closing starts, 1013 * rather than once it has finished. 1014 * 1015 * <p>After calling this method, you may not call {@link 1016 * #finishToValueAndCloser(ValueAndCloserConsumer, Executor)}, this method, or any other 1017 * derivation method on this {@code ClosingFuture}. 1018 * 1019 * @return a {@link Future} that represents the final value or exception of the pipeline 1020 */ 1021 public FluentFuture<V> finishToFuture() { 1022 if (compareAndUpdateState(OPEN, WILL_CLOSE)) { 1023 logger.log(FINER, "will close {0}", this); 1024 future.addListener( 1025 new Runnable() { 1026 @Override 1027 public void run() { 1028 checkAndUpdateState(WILL_CLOSE, CLOSING); 1029 close(); 1030 checkAndUpdateState(CLOSING, CLOSED); 1031 } 1032 }, 1033 directExecutor()); 1034 } else { 1035 switch (state.get()) { 1036 case SUBSUMED: 1037 throw new IllegalStateException( 1038 "Cannot call finishToFuture() after deriving another step"); 1039 1040 case WILL_CREATE_VALUE_AND_CLOSER: 1041 throw new IllegalStateException( 1042 "Cannot call finishToFuture() after calling finishToValueAndCloser()"); 1043 1044 case WILL_CLOSE: 1045 case CLOSING: 1046 case CLOSED: 1047 throw new IllegalStateException("Cannot call finishToFuture() twice"); 1048 1049 case OPEN: 1050 throw new AssertionError(); 1051 } 1052 } 1053 return future; 1054 } 1055 1056 /** 1057 * Marks this step as the last step in the {@code ClosingFuture} pipeline. When this step is done, 1058 * {@code receiver} will be called with an object that contains the result of the operation. The 1059 * receiver can store the {@link ValueAndCloser} outside the receiver for later synchronous use. 1060 * 1061 * <p>After calling this method, you may not call {@link #finishToFuture()}, this method again, or 1062 * any other derivation method on this {@code ClosingFuture}. 1063 * 1064 * @param consumer a callback whose method will be called (using {@code executor}) when this 1065 * operation is done 1066 */ 1067 public void finishToValueAndCloser( 1068 final ValueAndCloserConsumer<? super V> consumer, Executor executor) { 1069 checkNotNull(consumer); 1070 if (!compareAndUpdateState(OPEN, WILL_CREATE_VALUE_AND_CLOSER)) { 1071 switch (state.get()) { 1072 case SUBSUMED: 1073 throw new IllegalStateException( 1074 "Cannot call finishToValueAndCloser() after deriving another step"); 1075 1076 case WILL_CLOSE: 1077 case CLOSING: 1078 case CLOSED: 1079 throw new IllegalStateException( 1080 "Cannot call finishToValueAndCloser() after calling finishToFuture()"); 1081 1082 case WILL_CREATE_VALUE_AND_CLOSER: 1083 throw new IllegalStateException("Cannot call finishToValueAndCloser() twice"); 1084 1085 case OPEN: 1086 break; 1087 } 1088 throw new AssertionError(state); 1089 } 1090 future.addListener( 1091 new Runnable() { 1092 @Override 1093 public void run() { 1094 provideValueAndCloser(consumer, ClosingFuture.this); 1095 } 1096 }, 1097 executor); 1098 } 1099 1100 private static <C extends @Nullable Object, V extends C> void provideValueAndCloser( 1101 ValueAndCloserConsumer<C> consumer, ClosingFuture<V> closingFuture) { 1102 consumer.accept(new ValueAndCloser<C>(closingFuture)); 1103 } 1104 1105 /** 1106 * Attempts to cancel execution of this step. This attempt will fail if the step has already 1107 * completed, has already been cancelled, or could not be cancelled for some other reason. If 1108 * successful, and this step has not started when {@code cancel} is called, this step should never 1109 * run. 1110 * 1111 * <p>If successful, causes the objects captured by this step (if already started) and its input 1112 * step(s) for later closing to be closed on their respective {@link Executor}s. If any such calls 1113 * specified {@link MoreExecutors#directExecutor()}, those objects will be closed synchronously. 1114 * 1115 * @param mayInterruptIfRunning {@code true} if the thread executing this task should be 1116 * interrupted; otherwise, in-progress tasks are allowed to complete, but the step will be 1117 * cancelled regardless 1118 * @return {@code false} if the step could not be cancelled, typically because it has already 1119 * completed normally; {@code true} otherwise 1120 */ 1121 @CanIgnoreReturnValue 1122 public boolean cancel(boolean mayInterruptIfRunning) { 1123 logger.log(FINER, "cancelling {0}", this); 1124 boolean cancelled = future.cancel(mayInterruptIfRunning); 1125 if (cancelled) { 1126 close(); 1127 } 1128 return cancelled; 1129 } 1130 1131 private void close() { 1132 logger.log(FINER, "closing {0}", this); 1133 closeables.close(); 1134 } 1135 1136 private <U extends @Nullable Object> ClosingFuture<U> derive(FluentFuture<U> future) { 1137 ClosingFuture<U> derived = new ClosingFuture<>(future); 1138 becomeSubsumedInto(derived.closeables); 1139 return derived; 1140 } 1141 1142 private void becomeSubsumedInto(CloseableList otherCloseables) { 1143 checkAndUpdateState(OPEN, SUBSUMED); 1144 otherCloseables.add(closeables, directExecutor()); 1145 } 1146 1147 /** 1148 * An object that can return the value of the {@link ClosingFuture}s that are passed to {@link 1149 * #whenAllComplete(Iterable)} or {@link #whenAllSucceed(Iterable)}. 1150 * 1151 * <p>Only for use by a {@link CombiningCallable} or {@link AsyncCombiningCallable} object. 1152 */ 1153 public static final class Peeker { 1154 private final ImmutableList<ClosingFuture<?>> futures; 1155 private volatile boolean beingCalled; 1156 1157 private Peeker(ImmutableList<ClosingFuture<?>> futures) { 1158 this.futures = checkNotNull(futures); 1159 } 1160 1161 /** 1162 * Returns the value of {@code closingFuture}. 1163 * 1164 * @throws ExecutionException if {@code closingFuture} is a failed step 1165 * @throws CancellationException if the {@code closingFuture}'s future was cancelled 1166 * @throws IllegalArgumentException if {@code closingFuture} is not one of the futures passed to 1167 * {@link #whenAllComplete(Iterable)} or {@link #whenAllComplete(Iterable)} 1168 * @throws IllegalStateException if called outside of a call to {@link 1169 * CombiningCallable#call(DeferredCloser, Peeker)} or {@link 1170 * AsyncCombiningCallable#call(DeferredCloser, Peeker)} 1171 */ 1172 @ParametricNullness 1173 public final <D extends @Nullable Object> D getDone(ClosingFuture<D> closingFuture) 1174 throws ExecutionException { 1175 checkState(beingCalled); 1176 checkArgument(futures.contains(closingFuture)); 1177 return Futures.getDone(closingFuture.future); 1178 } 1179 1180 @ParametricNullness 1181 private <V extends @Nullable Object> V call( 1182 CombiningCallable<V> combiner, CloseableList closeables) throws Exception { 1183 beingCalled = true; 1184 CloseableList newCloseables = new CloseableList(); 1185 try { 1186 return combiner.call(newCloseables.closer, this); 1187 } finally { 1188 closeables.add(newCloseables, directExecutor()); 1189 beingCalled = false; 1190 } 1191 } 1192 1193 private <V extends @Nullable Object> FluentFuture<V> callAsync( 1194 AsyncCombiningCallable<V> combiner, CloseableList closeables) throws Exception { 1195 beingCalled = true; 1196 CloseableList newCloseables = new CloseableList(); 1197 try { 1198 ClosingFuture<V> closingFuture = combiner.call(newCloseables.closer, this); 1199 closingFuture.becomeSubsumedInto(closeables); 1200 return closingFuture.future; 1201 } finally { 1202 closeables.add(newCloseables, directExecutor()); 1203 beingCalled = false; 1204 } 1205 } 1206 } 1207 1208 /** 1209 * A builder of a {@link ClosingFuture} step that is derived from more than one input step. 1210 * 1211 * <p>See {@link #whenAllComplete(Iterable)} and {@link #whenAllSucceed(Iterable)} for how to 1212 * instantiate this class. 1213 * 1214 * <p>Example: 1215 * 1216 * <pre>{@code 1217 * final ClosingFuture<BufferedReader> file1ReaderFuture = ...; 1218 * final ClosingFuture<BufferedReader> file2ReaderFuture = ...; 1219 * ListenableFuture<Integer> numberOfDifferentLines = 1220 * ClosingFuture.whenAllSucceed(file1ReaderFuture, file2ReaderFuture) 1221 * .call( 1222 * (closer, peeker) -> { 1223 * BufferedReader file1Reader = peeker.getDone(file1ReaderFuture); 1224 * BufferedReader file2Reader = peeker.getDone(file2ReaderFuture); 1225 * return countDifferentLines(file1Reader, file2Reader); 1226 * }, 1227 * executor) 1228 * .closing(executor); 1229 * }</pre> 1230 */ 1231 // TODO(cpovirk): Use simple name instead of fully qualified after we stop building with JDK 8. 1232 @com.google.errorprone.annotations.DoNotMock( 1233 "Use ClosingFuture.whenAllSucceed() or .whenAllComplete() instead.") 1234 public static class Combiner { 1235 1236 private final CloseableList closeables = new CloseableList(); 1237 1238 /** 1239 * An operation that returns a result and may throw an exception. 1240 * 1241 * @param <V> the type of the result 1242 */ 1243 @FunctionalInterface 1244 public interface CombiningCallable<V extends @Nullable Object> { 1245 /** 1246 * Computes a result, or throws an exception if unable to do so. 1247 * 1248 * <p>Any objects that are passed to {@link DeferredCloser#eventuallyClose(Closeable, 1249 * Executor) closer.eventuallyClose()} will be closed when the {@link ClosingFuture} pipeline 1250 * is done (but not before this method completes), even if this method throws or the pipeline 1251 * is cancelled. 1252 * 1253 * @param peeker used to get the value of any of the input futures 1254 */ 1255 @ParametricNullness 1256 V call(DeferredCloser closer, Peeker peeker) throws Exception; 1257 } 1258 1259 /** 1260 * An operation that returns a {@link ClosingFuture} result and may throw an exception. 1261 * 1262 * @param <V> the type of the result 1263 */ 1264 @FunctionalInterface 1265 public interface AsyncCombiningCallable<V extends @Nullable Object> { 1266 /** 1267 * Computes a {@link ClosingFuture} result, or throws an exception if unable to do so. 1268 * 1269 * <p>Any objects that are passed to {@link DeferredCloser#eventuallyClose(Closeable, 1270 * Executor) closer.eventuallyClose()} will be closed when the {@link ClosingFuture} pipeline 1271 * is done (but not before this method completes), even if this method throws or the pipeline 1272 * is cancelled. 1273 * 1274 * @param peeker used to get the value of any of the input futures 1275 */ 1276 ClosingFuture<V> call(DeferredCloser closer, Peeker peeker) throws Exception; 1277 } 1278 1279 private final boolean allMustSucceed; 1280 protected final ImmutableList<ClosingFuture<?>> inputs; 1281 1282 private Combiner(boolean allMustSucceed, Iterable<? extends ClosingFuture<?>> inputs) { 1283 this.allMustSucceed = allMustSucceed; 1284 this.inputs = ImmutableList.copyOf(inputs); 1285 for (ClosingFuture<?> input : inputs) { 1286 input.becomeSubsumedInto(closeables); 1287 } 1288 } 1289 1290 /** 1291 * Returns a new {@code ClosingFuture} pipeline step derived from the inputs by applying a 1292 * combining function to their values. The function can use a {@link DeferredCloser} to capture 1293 * objects to be closed when the pipeline is done. 1294 * 1295 * <p>If this combiner was returned by a {@link #whenAllSucceed} method and any of the inputs 1296 * fail, so will the returned step. 1297 * 1298 * <p>If the combiningCallable throws a {@code CancellationException}, the pipeline will be 1299 * cancelled. 1300 * 1301 * <p>If the combiningCallable throws an {@code ExecutionException}, the cause of the thrown 1302 * {@code ExecutionException} will be extracted and used as the failure of the derived step. 1303 */ 1304 public <V extends @Nullable Object> ClosingFuture<V> call( 1305 final CombiningCallable<V> combiningCallable, Executor executor) { 1306 Callable<V> callable = 1307 new Callable<V>() { 1308 @Override 1309 @ParametricNullness 1310 public V call() throws Exception { 1311 return new Peeker(inputs).call(combiningCallable, closeables); 1312 } 1313 1314 @Override 1315 public String toString() { 1316 return combiningCallable.toString(); 1317 } 1318 }; 1319 ClosingFuture<V> derived = new ClosingFuture<>(futureCombiner().call(callable, executor)); 1320 derived.closeables.add(closeables, directExecutor()); 1321 return derived; 1322 } 1323 1324 /** 1325 * Returns a new {@code ClosingFuture} pipeline step derived from the inputs by applying a 1326 * {@code ClosingFuture}-returning function to their values. The function can use a {@link 1327 * DeferredCloser} to capture objects to be closed when the pipeline is done (other than those 1328 * captured by the returned {@link ClosingFuture}). 1329 * 1330 * <p>If this combiner was returned by a {@link #whenAllSucceed} method and any of the inputs 1331 * fail, so will the returned step. 1332 * 1333 * <p>If the combiningCallable throws a {@code CancellationException}, the pipeline will be 1334 * cancelled. 1335 * 1336 * <p>If the combiningCallable throws an {@code ExecutionException}, the cause of the thrown 1337 * {@code ExecutionException} will be extracted and used as the failure of the derived step. 1338 * 1339 * <p>If the combiningCallable throws any other exception, it will be used as the failure of the 1340 * derived step. 1341 * 1342 * <p>If an exception is thrown after the combiningCallable creates a {@code ClosingFuture}, 1343 * then none of the closeable objects in that {@code ClosingFuture} will be closed. 1344 * 1345 * <p>Usage guidelines for this method: 1346 * 1347 * <ul> 1348 * <li>Use this method only when calling an API that returns a {@link ListenableFuture} or a 1349 * {@code ClosingFuture}. If possible, prefer calling {@link #call(CombiningCallable, 1350 * Executor)} instead, with a function that returns the next value directly. 1351 * <li>Call {@link DeferredCloser#eventuallyClose(Closeable, Executor) 1352 * closer.eventuallyClose()} for every closeable object this step creates in order to 1353 * capture it for later closing. 1354 * <li>Return a {@code ClosingFuture}. To turn a {@link ListenableFuture} into a {@code 1355 * ClosingFuture} call {@link #from(ListenableFuture)}. 1356 * </ul> 1357 * 1358 * <p>The same warnings about doing heavyweight operations within {@link 1359 * ClosingFuture#transformAsync(AsyncClosingFunction, Executor)} apply here. 1360 */ 1361 public <V extends @Nullable Object> ClosingFuture<V> callAsync( 1362 final AsyncCombiningCallable<V> combiningCallable, Executor executor) { 1363 AsyncCallable<V> asyncCallable = 1364 new AsyncCallable<V>() { 1365 @Override 1366 public ListenableFuture<V> call() throws Exception { 1367 return new Peeker(inputs).callAsync(combiningCallable, closeables); 1368 } 1369 1370 @Override 1371 public String toString() { 1372 return combiningCallable.toString(); 1373 } 1374 }; 1375 ClosingFuture<V> derived = 1376 new ClosingFuture<>(futureCombiner().callAsync(asyncCallable, executor)); 1377 derived.closeables.add(closeables, directExecutor()); 1378 return derived; 1379 } 1380 1381 private FutureCombiner<@Nullable Object> futureCombiner() { 1382 return allMustSucceed 1383 ? Futures.whenAllSucceed(inputFutures()) 1384 : Futures.whenAllComplete(inputFutures()); 1385 } 1386 1387 private static final Function<ClosingFuture<?>, FluentFuture<?>> INNER_FUTURE = 1388 new Function<ClosingFuture<?>, FluentFuture<?>>() { 1389 @Override 1390 public FluentFuture<?> apply(ClosingFuture<?> future) { 1391 return future.future; 1392 } 1393 }; 1394 1395 private ImmutableList<FluentFuture<?>> inputFutures() { 1396 return FluentIterable.from(inputs).transform(INNER_FUTURE).toList(); 1397 } 1398 } 1399 1400 /** 1401 * A generic {@link Combiner} that lets you use a lambda or method reference to combine two {@link 1402 * ClosingFuture}s. Use {@link #whenAllSucceed(ClosingFuture, ClosingFuture)} to start this 1403 * combination. 1404 * 1405 * @param <V1> the type returned by the first future 1406 * @param <V2> the type returned by the second future 1407 */ 1408 public static final class Combiner2<V1 extends @Nullable Object, V2 extends @Nullable Object> 1409 extends Combiner { 1410 1411 /** 1412 * A function that returns a value when applied to the values of the two futures passed to 1413 * {@link #whenAllSucceed(ClosingFuture, ClosingFuture)}. 1414 * 1415 * @param <V1> the type returned by the first future 1416 * @param <V2> the type returned by the second future 1417 * @param <U> the type returned by the function 1418 */ 1419 @FunctionalInterface 1420 public interface ClosingFunction2< 1421 V1 extends @Nullable Object, V2 extends @Nullable Object, U extends @Nullable Object> { 1422 1423 /** 1424 * Applies this function to two inputs, or throws an exception if unable to do so. 1425 * 1426 * <p>Any objects that are passed to {@link DeferredCloser#eventuallyClose(Closeable, 1427 * Executor) closer.eventuallyClose()} will be closed when the {@link ClosingFuture} pipeline 1428 * is done (but not before this method completes), even if this method throws or the pipeline 1429 * is cancelled. 1430 */ 1431 @ParametricNullness 1432 U apply(DeferredCloser closer, @ParametricNullness V1 value1, @ParametricNullness V2 value2) 1433 throws Exception; 1434 } 1435 1436 /** 1437 * A function that returns a {@link ClosingFuture} when applied to the values of the two futures 1438 * passed to {@link #whenAllSucceed(ClosingFuture, ClosingFuture)}. 1439 * 1440 * @param <V1> the type returned by the first future 1441 * @param <V2> the type returned by the second future 1442 * @param <U> the type returned by the function 1443 */ 1444 @FunctionalInterface 1445 public interface AsyncClosingFunction2< 1446 V1 extends @Nullable Object, V2 extends @Nullable Object, U extends @Nullable Object> { 1447 1448 /** 1449 * Applies this function to two inputs, or throws an exception if unable to do so. 1450 * 1451 * <p>Any objects that are passed to {@link DeferredCloser#eventuallyClose(Closeable, 1452 * Executor) closer.eventuallyClose()} will be closed when the {@link ClosingFuture} pipeline 1453 * is done (but not before this method completes), even if this method throws or the pipeline 1454 * is cancelled. 1455 */ 1456 ClosingFuture<U> apply( 1457 DeferredCloser closer, @ParametricNullness V1 value1, @ParametricNullness V2 value2) 1458 throws Exception; 1459 } 1460 1461 private final ClosingFuture<V1> future1; 1462 private final ClosingFuture<V2> future2; 1463 1464 private Combiner2(ClosingFuture<V1> future1, ClosingFuture<V2> future2) { 1465 super(true, ImmutableList.of(future1, future2)); 1466 this.future1 = future1; 1467 this.future2 = future2; 1468 } 1469 1470 /** 1471 * Returns a new {@code ClosingFuture} pipeline step derived from the inputs by applying a 1472 * combining function to their values. The function can use a {@link DeferredCloser} to capture 1473 * objects to be closed when the pipeline is done. 1474 * 1475 * <p>If this combiner was returned by {@link #whenAllSucceed(ClosingFuture, ClosingFuture)} and 1476 * any of the inputs fail, so will the returned step. 1477 * 1478 * <p>If the function throws a {@code CancellationException}, the pipeline will be cancelled. 1479 * 1480 * <p>If the function throws an {@code ExecutionException}, the cause of the thrown {@code 1481 * ExecutionException} will be extracted and used as the failure of the derived step. 1482 */ 1483 public <U extends @Nullable Object> ClosingFuture<U> call( 1484 final ClosingFunction2<V1, V2, U> function, Executor executor) { 1485 return call( 1486 new CombiningCallable<U>() { 1487 @Override 1488 @ParametricNullness 1489 public U call(DeferredCloser closer, Peeker peeker) throws Exception { 1490 return function.apply(closer, peeker.getDone(future1), peeker.getDone(future2)); 1491 } 1492 1493 @Override 1494 public String toString() { 1495 return function.toString(); 1496 } 1497 }, 1498 executor); 1499 } 1500 1501 /** 1502 * Returns a new {@code ClosingFuture} pipeline step derived from the inputs by applying a 1503 * {@code ClosingFuture}-returning function to their values. The function can use a {@link 1504 * DeferredCloser} to capture objects to be closed when the pipeline is done (other than those 1505 * captured by the returned {@link ClosingFuture}). 1506 * 1507 * <p>If this combiner was returned by {@link #whenAllSucceed(ClosingFuture, ClosingFuture)} and 1508 * any of the inputs fail, so will the returned step. 1509 * 1510 * <p>If the function throws a {@code CancellationException}, the pipeline will be cancelled. 1511 * 1512 * <p>If the function throws an {@code ExecutionException}, the cause of the thrown {@code 1513 * ExecutionException} will be extracted and used as the failure of the derived step. 1514 * 1515 * <p>If the function throws any other exception, it will be used as the failure of the derived 1516 * step. 1517 * 1518 * <p>If an exception is thrown after the function creates a {@code ClosingFuture}, then none of 1519 * the closeable objects in that {@code ClosingFuture} will be closed. 1520 * 1521 * <p>Usage guidelines for this method: 1522 * 1523 * <ul> 1524 * <li>Use this method only when calling an API that returns a {@link ListenableFuture} or a 1525 * {@code ClosingFuture}. If possible, prefer calling {@link #call(CombiningCallable, 1526 * Executor)} instead, with a function that returns the next value directly. 1527 * <li>Call {@link DeferredCloser#eventuallyClose(Closeable, Executor) 1528 * closer.eventuallyClose()} for every closeable object this step creates in order to 1529 * capture it for later closing. 1530 * <li>Return a {@code ClosingFuture}. To turn a {@link ListenableFuture} into a {@code 1531 * ClosingFuture} call {@link #from(ListenableFuture)}. 1532 * </ul> 1533 * 1534 * <p>The same warnings about doing heavyweight operations within {@link 1535 * ClosingFuture#transformAsync(AsyncClosingFunction, Executor)} apply here. 1536 */ 1537 public <U extends @Nullable Object> ClosingFuture<U> callAsync( 1538 final AsyncClosingFunction2<V1, V2, U> function, Executor executor) { 1539 return callAsync( 1540 new AsyncCombiningCallable<U>() { 1541 @Override 1542 public ClosingFuture<U> call(DeferredCloser closer, Peeker peeker) throws Exception { 1543 return function.apply(closer, peeker.getDone(future1), peeker.getDone(future2)); 1544 } 1545 1546 @Override 1547 public String toString() { 1548 return function.toString(); 1549 } 1550 }, 1551 executor); 1552 } 1553 } 1554 1555 /** 1556 * A generic {@link Combiner} that lets you use a lambda or method reference to combine three 1557 * {@link ClosingFuture}s. Use {@link #whenAllSucceed(ClosingFuture, ClosingFuture, 1558 * ClosingFuture)} to start this combination. 1559 * 1560 * @param <V1> the type returned by the first future 1561 * @param <V2> the type returned by the second future 1562 * @param <V3> the type returned by the third future 1563 */ 1564 public static final class Combiner3< 1565 V1 extends @Nullable Object, V2 extends @Nullable Object, V3 extends @Nullable Object> 1566 extends Combiner { 1567 /** 1568 * A function that returns a value when applied to the values of the three futures passed to 1569 * {@link #whenAllSucceed(ClosingFuture, ClosingFuture, ClosingFuture)}. 1570 * 1571 * @param <V1> the type returned by the first future 1572 * @param <V2> the type returned by the second future 1573 * @param <V3> the type returned by the third future 1574 * @param <U> the type returned by the function 1575 */ 1576 @FunctionalInterface 1577 public interface ClosingFunction3< 1578 V1 extends @Nullable Object, 1579 V2 extends @Nullable Object, 1580 V3 extends @Nullable Object, 1581 U extends @Nullable Object> { 1582 /** 1583 * Applies this function to three inputs, or throws an exception if unable to do so. 1584 * 1585 * <p>Any objects that are passed to {@link DeferredCloser#eventuallyClose(Closeable, 1586 * Executor) closer.eventuallyClose()} will be closed when the {@link ClosingFuture} pipeline 1587 * is done (but not before this method completes), even if this method throws or the pipeline 1588 * is cancelled. 1589 */ 1590 @ParametricNullness 1591 U apply( 1592 DeferredCloser closer, 1593 @ParametricNullness V1 value1, 1594 @ParametricNullness V2 value2, 1595 @ParametricNullness V3 value3) 1596 throws Exception; 1597 } 1598 1599 /** 1600 * A function that returns a {@link ClosingFuture} when applied to the values of the three 1601 * futures passed to {@link #whenAllSucceed(ClosingFuture, ClosingFuture, ClosingFuture)}. 1602 * 1603 * @param <V1> the type returned by the first future 1604 * @param <V2> the type returned by the second future 1605 * @param <V3> the type returned by the third future 1606 * @param <U> the type returned by the function 1607 */ 1608 @FunctionalInterface 1609 public interface AsyncClosingFunction3< 1610 V1 extends @Nullable Object, 1611 V2 extends @Nullable Object, 1612 V3 extends @Nullable Object, 1613 U extends @Nullable Object> { 1614 /** 1615 * Applies this function to three inputs, or throws an exception if unable to do so. 1616 * 1617 * <p>Any objects that are passed to {@link DeferredCloser#eventuallyClose(Closeable, 1618 * Executor) closer.eventuallyClose()} will be closed when the {@link ClosingFuture} pipeline 1619 * is done (but not before this method completes), even if this method throws or the pipeline 1620 * is cancelled. 1621 */ 1622 ClosingFuture<U> apply( 1623 DeferredCloser closer, 1624 @ParametricNullness V1 value1, 1625 @ParametricNullness V2 value2, 1626 @ParametricNullness V3 value3) 1627 throws Exception; 1628 } 1629 1630 private final ClosingFuture<V1> future1; 1631 private final ClosingFuture<V2> future2; 1632 private final ClosingFuture<V3> future3; 1633 1634 private Combiner3( 1635 ClosingFuture<V1> future1, ClosingFuture<V2> future2, ClosingFuture<V3> future3) { 1636 super(true, ImmutableList.of(future1, future2, future3)); 1637 this.future1 = future1; 1638 this.future2 = future2; 1639 this.future3 = future3; 1640 } 1641 1642 /** 1643 * Returns a new {@code ClosingFuture} pipeline step derived from the inputs by applying a 1644 * combining function to their values. The function can use a {@link DeferredCloser} to capture 1645 * objects to be closed when the pipeline is done. 1646 * 1647 * <p>If this combiner was returned by {@link #whenAllSucceed(ClosingFuture, ClosingFuture, 1648 * ClosingFuture)} and any of the inputs fail, so will the returned step. 1649 * 1650 * <p>If the function throws a {@code CancellationException}, the pipeline will be cancelled. 1651 * 1652 * <p>If the function throws an {@code ExecutionException}, the cause of the thrown {@code 1653 * ExecutionException} will be extracted and used as the failure of the derived step. 1654 */ 1655 public <U extends @Nullable Object> ClosingFuture<U> call( 1656 final ClosingFunction3<V1, V2, V3, U> function, Executor executor) { 1657 return call( 1658 new CombiningCallable<U>() { 1659 @Override 1660 @ParametricNullness 1661 public U call(DeferredCloser closer, Peeker peeker) throws Exception { 1662 return function.apply( 1663 closer, 1664 peeker.getDone(future1), 1665 peeker.getDone(future2), 1666 peeker.getDone(future3)); 1667 } 1668 1669 @Override 1670 public String toString() { 1671 return function.toString(); 1672 } 1673 }, 1674 executor); 1675 } 1676 1677 /** 1678 * Returns a new {@code ClosingFuture} pipeline step derived from the inputs by applying a 1679 * {@code ClosingFuture}-returning function to their values. The function can use a {@link 1680 * DeferredCloser} to capture objects to be closed when the pipeline is done (other than those 1681 * captured by the returned {@link ClosingFuture}). 1682 * 1683 * <p>If this combiner was returned by {@link #whenAllSucceed(ClosingFuture, ClosingFuture, 1684 * ClosingFuture)} and any of the inputs fail, so will the returned step. 1685 * 1686 * <p>If the function throws a {@code CancellationException}, the pipeline will be cancelled. 1687 * 1688 * <p>If the function throws an {@code ExecutionException}, the cause of the thrown {@code 1689 * ExecutionException} will be extracted and used as the failure of the derived step. 1690 * 1691 * <p>If the function throws any other exception, it will be used as the failure of the derived 1692 * step. 1693 * 1694 * <p>If an exception is thrown after the function creates a {@code ClosingFuture}, then none of 1695 * the closeable objects in that {@code ClosingFuture} will be closed. 1696 * 1697 * <p>Usage guidelines for this method: 1698 * 1699 * <ul> 1700 * <li>Use this method only when calling an API that returns a {@link ListenableFuture} or a 1701 * {@code ClosingFuture}. If possible, prefer calling {@link #call(CombiningCallable, 1702 * Executor)} instead, with a function that returns the next value directly. 1703 * <li>Call {@link DeferredCloser#eventuallyClose(Closeable, Executor) 1704 * closer.eventuallyClose()} for every closeable object this step creates in order to 1705 * capture it for later closing. 1706 * <li>Return a {@code ClosingFuture}. To turn a {@link ListenableFuture} into a {@code 1707 * ClosingFuture} call {@link #from(ListenableFuture)}. 1708 * </ul> 1709 * 1710 * <p>The same warnings about doing heavyweight operations within {@link 1711 * ClosingFuture#transformAsync(AsyncClosingFunction, Executor)} apply here. 1712 */ 1713 public <U extends @Nullable Object> ClosingFuture<U> callAsync( 1714 final AsyncClosingFunction3<V1, V2, V3, U> function, Executor executor) { 1715 return callAsync( 1716 new AsyncCombiningCallable<U>() { 1717 @Override 1718 public ClosingFuture<U> call(DeferredCloser closer, Peeker peeker) throws Exception { 1719 return function.apply( 1720 closer, 1721 peeker.getDone(future1), 1722 peeker.getDone(future2), 1723 peeker.getDone(future3)); 1724 } 1725 1726 @Override 1727 public String toString() { 1728 return function.toString(); 1729 } 1730 }, 1731 executor); 1732 } 1733 } 1734 1735 /** 1736 * A generic {@link Combiner} that lets you use a lambda or method reference to combine four 1737 * {@link ClosingFuture}s. Use {@link #whenAllSucceed(ClosingFuture, ClosingFuture, ClosingFuture, 1738 * ClosingFuture)} to start this combination. 1739 * 1740 * @param <V1> the type returned by the first future 1741 * @param <V2> the type returned by the second future 1742 * @param <V3> the type returned by the third future 1743 * @param <V4> the type returned by the fourth future 1744 */ 1745 public static final class Combiner4< 1746 V1 extends @Nullable Object, 1747 V2 extends @Nullable Object, 1748 V3 extends @Nullable Object, 1749 V4 extends @Nullable Object> 1750 extends Combiner { 1751 /** 1752 * A function that returns a value when applied to the values of the four futures passed to 1753 * {@link #whenAllSucceed(ClosingFuture, ClosingFuture, ClosingFuture, ClosingFuture)}. 1754 * 1755 * @param <V1> the type returned by the first future 1756 * @param <V2> the type returned by the second future 1757 * @param <V3> the type returned by the third future 1758 * @param <V4> the type returned by the fourth future 1759 * @param <U> the type returned by the function 1760 */ 1761 @FunctionalInterface 1762 public interface ClosingFunction4< 1763 V1 extends @Nullable Object, 1764 V2 extends @Nullable Object, 1765 V3 extends @Nullable Object, 1766 V4 extends @Nullable Object, 1767 U extends @Nullable Object> { 1768 /** 1769 * Applies this function to four inputs, or throws an exception if unable to do so. 1770 * 1771 * <p>Any objects that are passed to {@link DeferredCloser#eventuallyClose(Closeable, 1772 * Executor) closer.eventuallyClose()} will be closed when the {@link ClosingFuture} pipeline 1773 * is done (but not before this method completes), even if this method throws or the pipeline 1774 * is cancelled. 1775 */ 1776 @ParametricNullness 1777 U apply( 1778 DeferredCloser closer, 1779 @ParametricNullness V1 value1, 1780 @ParametricNullness V2 value2, 1781 @ParametricNullness V3 value3, 1782 @ParametricNullness V4 value4) 1783 throws Exception; 1784 } 1785 1786 /** 1787 * A function that returns a {@link ClosingFuture} when applied to the values of the four 1788 * futures passed to {@link #whenAllSucceed(ClosingFuture, ClosingFuture, ClosingFuture, 1789 * ClosingFuture)}. 1790 * 1791 * @param <V1> the type returned by the first future 1792 * @param <V2> the type returned by the second future 1793 * @param <V3> the type returned by the third future 1794 * @param <V4> the type returned by the fourth future 1795 * @param <U> the type returned by the function 1796 */ 1797 @FunctionalInterface 1798 public interface AsyncClosingFunction4< 1799 V1 extends @Nullable Object, 1800 V2 extends @Nullable Object, 1801 V3 extends @Nullable Object, 1802 V4 extends @Nullable Object, 1803 U extends @Nullable Object> { 1804 /** 1805 * Applies this function to four inputs, or throws an exception if unable to do so. 1806 * 1807 * <p>Any objects that are passed to {@link DeferredCloser#eventuallyClose(Closeable, 1808 * Executor) closer.eventuallyClose()} will be closed when the {@link ClosingFuture} pipeline 1809 * is done (but not before this method completes), even if this method throws or the pipeline 1810 * is cancelled. 1811 */ 1812 ClosingFuture<U> apply( 1813 DeferredCloser closer, 1814 @ParametricNullness V1 value1, 1815 @ParametricNullness V2 value2, 1816 @ParametricNullness V3 value3, 1817 @ParametricNullness V4 value4) 1818 throws Exception; 1819 } 1820 1821 private final ClosingFuture<V1> future1; 1822 private final ClosingFuture<V2> future2; 1823 private final ClosingFuture<V3> future3; 1824 private final ClosingFuture<V4> future4; 1825 1826 private Combiner4( 1827 ClosingFuture<V1> future1, 1828 ClosingFuture<V2> future2, 1829 ClosingFuture<V3> future3, 1830 ClosingFuture<V4> future4) { 1831 super(true, ImmutableList.of(future1, future2, future3, future4)); 1832 this.future1 = future1; 1833 this.future2 = future2; 1834 this.future3 = future3; 1835 this.future4 = future4; 1836 } 1837 1838 /** 1839 * Returns a new {@code ClosingFuture} pipeline step derived from the inputs by applying a 1840 * combining function to their values. The function can use a {@link DeferredCloser} to capture 1841 * objects to be closed when the pipeline is done. 1842 * 1843 * <p>If this combiner was returned by {@link #whenAllSucceed(ClosingFuture, ClosingFuture, 1844 * ClosingFuture, ClosingFuture)} and any of the inputs fail, so will the returned step. 1845 * 1846 * <p>If the function throws a {@code CancellationException}, the pipeline will be cancelled. 1847 * 1848 * <p>If the function throws an {@code ExecutionException}, the cause of the thrown {@code 1849 * ExecutionException} will be extracted and used as the failure of the derived step. 1850 */ 1851 public <U extends @Nullable Object> ClosingFuture<U> call( 1852 final ClosingFunction4<V1, V2, V3, V4, U> function, Executor executor) { 1853 return call( 1854 new CombiningCallable<U>() { 1855 @Override 1856 @ParametricNullness 1857 public U call(DeferredCloser closer, Peeker peeker) throws Exception { 1858 return function.apply( 1859 closer, 1860 peeker.getDone(future1), 1861 peeker.getDone(future2), 1862 peeker.getDone(future3), 1863 peeker.getDone(future4)); 1864 } 1865 1866 @Override 1867 public String toString() { 1868 return function.toString(); 1869 } 1870 }, 1871 executor); 1872 } 1873 1874 /** 1875 * Returns a new {@code ClosingFuture} pipeline step derived from the inputs by applying a 1876 * {@code ClosingFuture}-returning function to their values. The function can use a {@link 1877 * DeferredCloser} to capture objects to be closed when the pipeline is done (other than those 1878 * captured by the returned {@link ClosingFuture}). 1879 * 1880 * <p>If this combiner was returned by {@link #whenAllSucceed(ClosingFuture, ClosingFuture, 1881 * ClosingFuture, ClosingFuture)} and any of the inputs fail, so will the returned step. 1882 * 1883 * <p>If the function throws a {@code CancellationException}, the pipeline will be cancelled. 1884 * 1885 * <p>If the function throws an {@code ExecutionException}, the cause of the thrown {@code 1886 * ExecutionException} will be extracted and used as the failure of the derived step. 1887 * 1888 * <p>If the function throws any other exception, it will be used as the failure of the derived 1889 * step. 1890 * 1891 * <p>If an exception is thrown after the function creates a {@code ClosingFuture}, then none of 1892 * the closeable objects in that {@code ClosingFuture} will be closed. 1893 * 1894 * <p>Usage guidelines for this method: 1895 * 1896 * <ul> 1897 * <li>Use this method only when calling an API that returns a {@link ListenableFuture} or a 1898 * {@code ClosingFuture}. If possible, prefer calling {@link #call(CombiningCallable, 1899 * Executor)} instead, with a function that returns the next value directly. 1900 * <li>Call {@link DeferredCloser#eventuallyClose(Closeable, Executor) 1901 * closer.eventuallyClose()} for every closeable object this step creates in order to 1902 * capture it for later closing. 1903 * <li>Return a {@code ClosingFuture}. To turn a {@link ListenableFuture} into a {@code 1904 * ClosingFuture} call {@link #from(ListenableFuture)}. 1905 * </ul> 1906 * 1907 * <p>The same warnings about doing heavyweight operations within {@link 1908 * ClosingFuture#transformAsync(AsyncClosingFunction, Executor)} apply here. 1909 */ 1910 public <U extends @Nullable Object> ClosingFuture<U> callAsync( 1911 final AsyncClosingFunction4<V1, V2, V3, V4, U> function, Executor executor) { 1912 return callAsync( 1913 new AsyncCombiningCallable<U>() { 1914 @Override 1915 public ClosingFuture<U> call(DeferredCloser closer, Peeker peeker) throws Exception { 1916 return function.apply( 1917 closer, 1918 peeker.getDone(future1), 1919 peeker.getDone(future2), 1920 peeker.getDone(future3), 1921 peeker.getDone(future4)); 1922 } 1923 1924 @Override 1925 public String toString() { 1926 return function.toString(); 1927 } 1928 }, 1929 executor); 1930 } 1931 } 1932 1933 /** 1934 * A generic {@link Combiner} that lets you use a lambda or method reference to combine five 1935 * {@link ClosingFuture}s. Use {@link #whenAllSucceed(ClosingFuture, ClosingFuture, ClosingFuture, 1936 * ClosingFuture, ClosingFuture)} to start this combination. 1937 * 1938 * @param <V1> the type returned by the first future 1939 * @param <V2> the type returned by the second future 1940 * @param <V3> the type returned by the third future 1941 * @param <V4> the type returned by the fourth future 1942 * @param <V5> the type returned by the fifth future 1943 */ 1944 public static final class Combiner5< 1945 V1 extends @Nullable Object, 1946 V2 extends @Nullable Object, 1947 V3 extends @Nullable Object, 1948 V4 extends @Nullable Object, 1949 V5 extends @Nullable Object> 1950 extends Combiner { 1951 /** 1952 * A function that returns a value when applied to the values of the five futures passed to 1953 * {@link #whenAllSucceed(ClosingFuture, ClosingFuture, ClosingFuture, ClosingFuture, 1954 * ClosingFuture)}. 1955 * 1956 * @param <V1> the type returned by the first future 1957 * @param <V2> the type returned by the second future 1958 * @param <V3> the type returned by the third future 1959 * @param <V4> the type returned by the fourth future 1960 * @param <V5> the type returned by the fifth future 1961 * @param <U> the type returned by the function 1962 */ 1963 @FunctionalInterface 1964 public interface ClosingFunction5< 1965 V1 extends @Nullable Object, 1966 V2 extends @Nullable Object, 1967 V3 extends @Nullable Object, 1968 V4 extends @Nullable Object, 1969 V5 extends @Nullable Object, 1970 U extends @Nullable Object> { 1971 /** 1972 * Applies this function to five inputs, or throws an exception if unable to do so. 1973 * 1974 * <p>Any objects that are passed to {@link DeferredCloser#eventuallyClose(Closeable, 1975 * Executor) closer.eventuallyClose()} will be closed when the {@link ClosingFuture} pipeline 1976 * is done (but not before this method completes), even if this method throws or the pipeline 1977 * is cancelled. 1978 */ 1979 @ParametricNullness 1980 U apply( 1981 DeferredCloser closer, 1982 @ParametricNullness V1 value1, 1983 @ParametricNullness V2 value2, 1984 @ParametricNullness V3 value3, 1985 @ParametricNullness V4 value4, 1986 @ParametricNullness V5 value5) 1987 throws Exception; 1988 } 1989 1990 /** 1991 * A function that returns a {@link ClosingFuture} when applied to the values of the five 1992 * futures passed to {@link #whenAllSucceed(ClosingFuture, ClosingFuture, ClosingFuture, 1993 * ClosingFuture, ClosingFuture)}. 1994 * 1995 * @param <V1> the type returned by the first future 1996 * @param <V2> the type returned by the second future 1997 * @param <V3> the type returned by the third future 1998 * @param <V4> the type returned by the fourth future 1999 * @param <V5> the type returned by the fifth future 2000 * @param <U> the type returned by the function 2001 */ 2002 @FunctionalInterface 2003 public interface AsyncClosingFunction5< 2004 V1 extends @Nullable Object, 2005 V2 extends @Nullable Object, 2006 V3 extends @Nullable Object, 2007 V4 extends @Nullable Object, 2008 V5 extends @Nullable Object, 2009 U extends @Nullable Object> { 2010 /** 2011 * Applies this function to five inputs, or throws an exception if unable to do so. 2012 * 2013 * <p>Any objects that are passed to {@link DeferredCloser#eventuallyClose(Closeable, 2014 * Executor) closer.eventuallyClose()} will be closed when the {@link ClosingFuture} pipeline 2015 * is done (but not before this method completes), even if this method throws or the pipeline 2016 * is cancelled. 2017 */ 2018 ClosingFuture<U> apply( 2019 DeferredCloser closer, 2020 @ParametricNullness V1 value1, 2021 @ParametricNullness V2 value2, 2022 @ParametricNullness V3 value3, 2023 @ParametricNullness V4 value4, 2024 @ParametricNullness V5 value5) 2025 throws Exception; 2026 } 2027 2028 private final ClosingFuture<V1> future1; 2029 private final ClosingFuture<V2> future2; 2030 private final ClosingFuture<V3> future3; 2031 private final ClosingFuture<V4> future4; 2032 private final ClosingFuture<V5> future5; 2033 2034 private Combiner5( 2035 ClosingFuture<V1> future1, 2036 ClosingFuture<V2> future2, 2037 ClosingFuture<V3> future3, 2038 ClosingFuture<V4> future4, 2039 ClosingFuture<V5> future5) { 2040 super(true, ImmutableList.of(future1, future2, future3, future4, future5)); 2041 this.future1 = future1; 2042 this.future2 = future2; 2043 this.future3 = future3; 2044 this.future4 = future4; 2045 this.future5 = future5; 2046 } 2047 2048 /** 2049 * Returns a new {@code ClosingFuture} pipeline step derived from the inputs by applying a 2050 * combining function to their values. The function can use a {@link DeferredCloser} to capture 2051 * objects to be closed when the pipeline is done. 2052 * 2053 * <p>If this combiner was returned by {@link #whenAllSucceed(ClosingFuture, ClosingFuture, 2054 * ClosingFuture, ClosingFuture, ClosingFuture)} and any of the inputs fail, so will the 2055 * returned step. 2056 * 2057 * <p>If the function throws a {@code CancellationException}, the pipeline will be cancelled. 2058 * 2059 * <p>If the function throws an {@code ExecutionException}, the cause of the thrown {@code 2060 * ExecutionException} will be extracted and used as the failure of the derived step. 2061 */ 2062 public <U extends @Nullable Object> ClosingFuture<U> call( 2063 final ClosingFunction5<V1, V2, V3, V4, V5, U> function, Executor executor) { 2064 return call( 2065 new CombiningCallable<U>() { 2066 @Override 2067 @ParametricNullness 2068 public U call(DeferredCloser closer, Peeker peeker) throws Exception { 2069 return function.apply( 2070 closer, 2071 peeker.getDone(future1), 2072 peeker.getDone(future2), 2073 peeker.getDone(future3), 2074 peeker.getDone(future4), 2075 peeker.getDone(future5)); 2076 } 2077 2078 @Override 2079 public String toString() { 2080 return function.toString(); 2081 } 2082 }, 2083 executor); 2084 } 2085 2086 /** 2087 * Returns a new {@code ClosingFuture} pipeline step derived from the inputs by applying a 2088 * {@code ClosingFuture}-returning function to their values. The function can use a {@link 2089 * DeferredCloser} to capture objects to be closed when the pipeline is done (other than those 2090 * captured by the returned {@link ClosingFuture}). 2091 * 2092 * <p>If this combiner was returned by {@link #whenAllSucceed(ClosingFuture, ClosingFuture, 2093 * ClosingFuture, ClosingFuture, ClosingFuture)} and any of the inputs fail, so will the 2094 * returned step. 2095 * 2096 * <p>If the function throws a {@code CancellationException}, the pipeline will be cancelled. 2097 * 2098 * <p>If the function throws an {@code ExecutionException}, the cause of the thrown {@code 2099 * ExecutionException} will be extracted and used as the failure of the derived step. 2100 * 2101 * <p>If the function throws any other exception, it will be used as the failure of the derived 2102 * step. 2103 * 2104 * <p>If an exception is thrown after the function creates a {@code ClosingFuture}, then none of 2105 * the closeable objects in that {@code ClosingFuture} will be closed. 2106 * 2107 * <p>Usage guidelines for this method: 2108 * 2109 * <ul> 2110 * <li>Use this method only when calling an API that returns a {@link ListenableFuture} or a 2111 * {@code ClosingFuture}. If possible, prefer calling {@link #call(CombiningCallable, 2112 * Executor)} instead, with a function that returns the next value directly. 2113 * <li>Call {@link DeferredCloser#eventuallyClose(Closeable, Executor) 2114 * closer.eventuallyClose()} for every closeable object this step creates in order to 2115 * capture it for later closing. 2116 * <li>Return a {@code ClosingFuture}. To turn a {@link ListenableFuture} into a {@code 2117 * ClosingFuture} call {@link #from(ListenableFuture)}. 2118 * </ul> 2119 * 2120 * <p>The same warnings about doing heavyweight operations within {@link 2121 * ClosingFuture#transformAsync(AsyncClosingFunction, Executor)} apply here. 2122 */ 2123 public <U extends @Nullable Object> ClosingFuture<U> callAsync( 2124 final AsyncClosingFunction5<V1, V2, V3, V4, V5, U> function, Executor executor) { 2125 return callAsync( 2126 new AsyncCombiningCallable<U>() { 2127 @Override 2128 public ClosingFuture<U> call(DeferredCloser closer, Peeker peeker) throws Exception { 2129 return function.apply( 2130 closer, 2131 peeker.getDone(future1), 2132 peeker.getDone(future2), 2133 peeker.getDone(future3), 2134 peeker.getDone(future4), 2135 peeker.getDone(future5)); 2136 } 2137 2138 @Override 2139 public String toString() { 2140 return function.toString(); 2141 } 2142 }, 2143 executor); 2144 } 2145 } 2146 2147 @Override 2148 public String toString() { 2149 // TODO(dpb): Better toString, in the style of Futures.transform etc. 2150 return toStringHelper(this).add("state", state.get()).addValue(future).toString(); 2151 } 2152 2153 @Override 2154 protected void finalize() { 2155 if (state.get().equals(OPEN)) { 2156 logger.log(SEVERE, "Uh oh! An open ClosingFuture has leaked and will close: {0}", this); 2157 FluentFuture<V> unused = finishToFuture(); 2158 } 2159 } 2160 2161 private static void closeQuietly(@CheckForNull final AutoCloseable closeable, Executor executor) { 2162 if (closeable == null) { 2163 return; 2164 } 2165 try { 2166 executor.execute( 2167 new Runnable() { 2168 @Override 2169 public void run() { 2170 try { 2171 closeable.close(); 2172 } catch (Exception e) { 2173 restoreInterruptIfIsInterruptedException(e); 2174 logger.log(WARNING, "thrown by close()", e); 2175 } 2176 } 2177 }); 2178 } catch (RejectedExecutionException e) { 2179 if (logger.isLoggable(WARNING)) { 2180 logger.log( 2181 WARNING, String.format("while submitting close to %s; will close inline", executor), e); 2182 } 2183 closeQuietly(closeable, directExecutor()); 2184 } 2185 } 2186 2187 private void checkAndUpdateState(State oldState, State newState) { 2188 checkState( 2189 compareAndUpdateState(oldState, newState), 2190 "Expected state to be %s, but it was %s", 2191 oldState, 2192 newState); 2193 } 2194 2195 private boolean compareAndUpdateState(State oldState, State newState) { 2196 return state.compareAndSet(oldState, newState); 2197 } 2198 2199 // TODO(dpb): Should we use a pair of ArrayLists instead of an IdentityHashMap? 2200 private static final class CloseableList extends IdentityHashMap<AutoCloseable, Executor> 2201 implements Closeable { 2202 private final DeferredCloser closer = new DeferredCloser(this); 2203 private volatile boolean closed; 2204 @CheckForNull private volatile CountDownLatch whenClosed; 2205 2206 <V extends @Nullable Object, U extends @Nullable Object> 2207 ListenableFuture<U> applyClosingFunction( 2208 ClosingFunction<? super V, U> transformation, @ParametricNullness V input) 2209 throws Exception { 2210 // TODO(dpb): Consider ways to defer closing without creating a separate CloseableList. 2211 CloseableList newCloseables = new CloseableList(); 2212 try { 2213 return immediateFuture(transformation.apply(newCloseables.closer, input)); 2214 } finally { 2215 add(newCloseables, directExecutor()); 2216 } 2217 } 2218 2219 <V extends @Nullable Object, U extends @Nullable Object> 2220 FluentFuture<U> applyAsyncClosingFunction( 2221 AsyncClosingFunction<V, U> transformation, @ParametricNullness V input) 2222 throws Exception { 2223 // TODO(dpb): Consider ways to defer closing without creating a separate CloseableList. 2224 CloseableList newCloseables = new CloseableList(); 2225 try { 2226 ClosingFuture<U> closingFuture = transformation.apply(newCloseables.closer, input); 2227 closingFuture.becomeSubsumedInto(newCloseables); 2228 return closingFuture.future; 2229 } finally { 2230 add(newCloseables, directExecutor()); 2231 } 2232 } 2233 2234 @Override 2235 public void close() { 2236 if (closed) { 2237 return; 2238 } 2239 synchronized (this) { 2240 if (closed) { 2241 return; 2242 } 2243 closed = true; 2244 } 2245 for (Map.Entry<AutoCloseable, Executor> entry : entrySet()) { 2246 closeQuietly(entry.getKey(), entry.getValue()); 2247 } 2248 clear(); 2249 if (whenClosed != null) { 2250 whenClosed.countDown(); 2251 } 2252 } 2253 2254 void add(@CheckForNull AutoCloseable closeable, Executor executor) { 2255 checkNotNull(executor); 2256 if (closeable == null) { 2257 return; 2258 } 2259 synchronized (this) { 2260 if (!closed) { 2261 put(closeable, executor); 2262 return; 2263 } 2264 } 2265 closeQuietly(closeable, executor); 2266 } 2267 2268 /** 2269 * Returns a latch that reaches zero when this objects' deferred closeables have been closed. 2270 */ 2271 CountDownLatch whenClosedCountDown() { 2272 if (closed) { 2273 return new CountDownLatch(0); 2274 } 2275 synchronized (this) { 2276 if (closed) { 2277 return new CountDownLatch(0); 2278 } 2279 checkState(whenClosed == null); 2280 return whenClosed = new CountDownLatch(1); 2281 } 2282 } 2283 } 2284 2285 /** 2286 * Returns an object that can be used to wait until this objects' deferred closeables have all had 2287 * {@link Runnable}s that close them submitted to each one's closing {@link Executor}. 2288 */ 2289 @VisibleForTesting 2290 CountDownLatch whenClosedCountDown() { 2291 return closeables.whenClosedCountDown(); 2292 } 2293 2294 /** The state of a {@link CloseableList}. */ 2295 enum State { 2296 /** The {@link CloseableList} has not been subsumed or closed. */ 2297 OPEN, 2298 2299 /** 2300 * The {@link CloseableList} has been subsumed into another. It may not be closed or subsumed 2301 * into any other. 2302 */ 2303 SUBSUMED, 2304 2305 /** 2306 * Some {@link ListenableFuture} has a callback attached that will close the {@link 2307 * CloseableList}, but it has not yet run. The {@link CloseableList} may not be subsumed. 2308 */ 2309 WILL_CLOSE, 2310 2311 /** 2312 * The callback that closes the {@link CloseableList} is running, but it has not completed. The 2313 * {@link CloseableList} may not be subsumed. 2314 */ 2315 CLOSING, 2316 2317 /** The {@link CloseableList} has been closed. It may not be further subsumed. */ 2318 CLOSED, 2319 2320 /** 2321 * {@link ClosingFuture#finishToValueAndCloser(ValueAndCloserConsumer, Executor)} has been 2322 * called. The step may not be further subsumed, nor may {@link #finishToFuture()} be called. 2323 */ 2324 WILL_CREATE_VALUE_AND_CLOSER, 2325 } 2326}