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