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