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