Top Description Inners Fields Constructors Methods
com.google.common.util.concurrent

public final Class ClosingFuture<V extends @Nullable Object>

extends Object
Class Inheritance
Annotations
@DoNotMock:Use ClosingFuture.from(Futures.immediate*Future)
@J2ktIncompatible
@ElementTypesAreNonnullByDefault
Type Parameters
<V>
the type of the value of this step
Static Imports
com.google.common.base.Functions.constant, .MoreObjects.toStringHelper, .Preconditions.checkArgument, .Preconditions.checkNotNull, .Preconditions.checkState, com.google.common.collect.Lists.asList, com.google.common.util.concurrent.ClosingFuture.State.CLOSED, .ClosingFuture.State.CLOSING, .ClosingFuture.State.OPEN, .ClosingFuture.State.SUBSUMED, .ClosingFuture.State.WILL_CLOSE, .ClosingFuture.State.WILL_CREATE_VALUE_AND_CLOSER, .Futures.getDone, .Futures.immediateFuture, .Futures.nonCancellationPropagating, .MoreExecutors.directExecutor, .Platform.restoreInterruptIfIsInterruptedException, java.util.logging.Level.FINER, .Level.SEVERE, .Level.WARNING

A step in a pipeline of an asynchronous computation. When the last step in the computation is complete, some objects captured during the computation are closed.

A pipeline of ClosingFutures is a tree of steps. Each step represents either an asynchronously-computed intermediate value, or else an exception that indicates the failure or cancellation of the operation so far. The only way to extract the value or exception from a step is by declaring that step to be the last step of the pipeline. Nevertheless, we refer to the "value" of a successful step or the "result" (value or exception) of any step.

  1. A pipeline starts at its leaf step (or steps), which is created from either a callable block or a ListenableFuture.
  2. Each other step is derived from one or more input steps. At each step, zero or more objects can be captured for later closing.
  3. There is one last step (the root of the tree), from which you can extract the final result of the computation. After that result is available (or the computation fails), all objects captured by any of the steps in the pipeline are closed.

Starting a pipeline

Start a ClosingFuture pipeline from a callable block that may capture objects for later closing. To start a pipeline from a ListenableFuture that doesn't create resources that should be closed later, you can use from(ListenableFuture) instead.

Derived steps

A ClosingFuture step can be derived from one or more input ClosingFuture steps in ways similar to FluentFutures: Each derivation can capture the next value or any intermediate objects for later closing.

A step can be the input to at most one derived step. Once you transform its value, catch its exception, or combine it with others, you cannot do anything else with it, including declare it to be the last step of the pipeline.

Transforming

To derive the next step by asynchronously applying a function to an input step's value, call transform(ClosingFunction, Executor) or transformAsync(AsyncClosingFunction, Executor) on the input step.

Catching

To derive the next step from a failed input step, call catching(Class, ClosingFunction, Executor) or catchingAsync(Class, AsyncClosingFunction, Executor) on the input step.

Combining

To derive a ClosingFuture from two or more input steps, pass the input steps to whenAllComplete(Iterable) or whenAllSucceed(Iterable) or its overloads.

Cancelling

Any step in a pipeline can be cancelled, even after another step has been derived, with the same semantics as cancelling a Future. In addition, a successfully cancelled step will immediately start closing all objects captured for later closing by it and by its input steps.

Ending a pipeline

Each ClosingFuture pipeline must be ended. To end a pipeline, decide whether you want to close the captured objects automatically or manually.

Automatically closing

You can extract a Future that represents the result of the last step in the pipeline by calling finishToFuture(). All objects the pipeline has captured for closing will begin to be closed asynchronously after the returned Future is done: the future completes before closing starts, rather than once it has finished.
FluentFuture<UserName> userName =
    ClosingFuture.submit(
            closer -> closer.eventuallyClose(database.newTransaction(), closingExecutor),
            executor)
        .transformAsync((closer, transaction) -> transaction.queryClosingFuture("..."), executor)
        .transform((closer, result) -> result.get("userName"), directExecutor())
        .catching(DBException.class, e -> "no user", directExecutor())
        .finishToFuture();
In this example, when the userName Future is done, the transaction and the query result cursor will both be closed, even if the operation is cancelled or fails.

Manually closing

If you want to close the captured objects manually, after you've used the final result, call finishToValueAndCloser(ValueAndCloserConsumer, Executor) to get an object that holds the final result. You then call ValueAndCloser#closeAsync() to close the captured objects.
ClosingFuture.submit(
            closer -> closer.eventuallyClose(database.newTransaction(), closingExecutor),
            executor)
    .transformAsync((closer, transaction) -> transaction.queryClosingFuture("..."), executor)
    .transform((closer, result) -> result.get("userName"), directExecutor())
    .catching(DBException.class, e -> "no user", directExecutor())
    .finishToValueAndCloser(
        valueAndCloser -> this.userNameValueAndCloser = valueAndCloser, executor);

// later
try { // get() will throw if the operation failed or was cancelled.
  UserName userName = userNameValueAndCloser.get();
  // do something with userName
} finally {
  userNameValueAndCloser.closeAsync();
}
In this example, when userNameValueAndCloser.closeAsync() is called, the transaction and the query result cursor will both be closed, even if the operation is cancelled or fails.

Note that if you don't call closeAsync(), the captured objects will not be closed. The automatic-closing approach described above is safer.

Since
30.0

Nested and Inner Type Summary

Modifier and TypeClass and Description
public static interface
ClosingFuture.AsyncClosingCallable<
the type of the result
V extends @Nullable Object
>

An operation that computes a ClosingFuture of a result.

public static interface
ClosingFuture.AsyncClosingFunction<
the type of the input to the function
T extends @Nullable Object
,
the type of the result of the function
U extends @Nullable Object
>

A function from an input to a ClosingFuture of a result.

private static class
public static interface
ClosingFuture.ClosingCallable<
the type of the result
V extends @Nullable Object
>

An operation that computes a result.

public static interface
ClosingFuture.ClosingFunction<
the type of the input to the function
T extends @Nullable Object
,
the type of the result of the function
U extends @Nullable Object
>

A function from an input to a result.

public static class
ClosingFuture.Combiner

A builder of a ClosingFuture step that is derived from more than one input step.

public static class
ClosingFuture.Combiner2<
the type returned by the first future
V1 extends @Nullable Object
,
the type returned by the second future
V2 extends @Nullable Object
>

A generic Combiner that lets you use a lambda or method reference to combine two ClosingFutures.

public static class
ClosingFuture.Combiner3<
the type returned by the first future
V1 extends @Nullable Object
,
the type returned by the second future
V2 extends @Nullable Object
,
the type returned by the third future
V3 extends @Nullable Object
>

A generic Combiner that lets you use a lambda or method reference to combine three ClosingFutures.

public static class
ClosingFuture.Combiner4<
the type returned by the first future
V1 extends @Nullable Object
,
the type returned by the second future
V2 extends @Nullable Object
,
the type returned by the third future
V3 extends @Nullable Object
,
the type returned by the fourth future
V4 extends @Nullable Object
>

A generic Combiner that lets you use a lambda or method reference to combine four ClosingFutures.

public static class
ClosingFuture.Combiner5<
the type returned by the first future
V1 extends @Nullable Object
,
the type returned by the second future
V2 extends @Nullable Object
,
the type returned by the third future
V3 extends @Nullable Object
,
the type returned by the fourth future
V4 extends @Nullable Object
,
the type returned by the fifth future
V5 extends @Nullable Object
>

A generic Combiner that lets you use a lambda or method reference to combine five ClosingFutures.

public static class
ClosingFuture.DeferredCloser

An object that can capture objects to be closed later, when a ClosingFuture pipeline is done.

public static class
ClosingFuture.Peeker

An object that can return the value of the ClosingFutures that are passed to whenAllComplete(Iterable) or whenAllSucceed(Iterable).

pack-priv static enum
public static class
ClosingFuture.ValueAndCloser<
the type of the value of a successful operation
V extends @Nullable Object
>

An object that holds the final result of an asynchronous ClosingFuture operation and allows the user to close all the closeable objects that were captured during it for later closing.

public static interface
ClosingFuture.ValueAndCloserConsumer<
the type of the final value of a successful pipeline
V extends @Nullable Object
>

Represents an operation that accepts a ValueAndCloser for the last step in a ClosingFuture pipeline.

Field Summary

Modifier and TypeField and Description
private final ClosingFuture.CloseableList
private final FluentFuture<V>
private static final LazyLogger
private final AtomicReference<ClosingFuture.State>

Constructor Summary

AccessConstructor and Description
private
private
ClosingFuture(final ClosingFuture.ClosingCallable<V> callable, Executor executor)

private

Method Summary

Modifier and TypeMethod and Description
private void
public boolean

Returns:

false if the step could not be cancelled, typically because it has already completed normally; true otherwise
cancel
(boolean
true if the thread executing this task should be interrupted; otherwise, in-progress tasks are allowed to complete, but the step will be cancelled regardless
mayInterruptIfRunning
)

Attempts to cancel execution of this step.

public <X extends Throwable> ClosingFuture<V>
catching(Class<X>
the exception type that triggers use of fallback. The exception type is matched against this step's exception. "This step's exception" means the cause of the ExecutionException thrown by Future#get() on the Future underlying this step or, if get() throws a different kind of exception, that exception itself. To avoid hiding bugs and other unrecoverable errors, callers should prefer more specific types, avoiding Throwable.class in particular.
exceptionType
,
ClosingFuture.ClosingFunction<? super X, ? extends V>
the function to be called if this step fails with the expected exception type. The function's argument is this step's exception. "This step's exception" means the cause of the ExecutionException thrown by Future#get() on the Future underlying this step or, if get() throws a different kind of exception, that exception itself.
fallback
,
Executor
the executor that runs fallback if the input fails
executor
)

Returns a new ClosingFuture pipeline step derived from this one by applying a function to its exception if it is an instance of a given exception type.

public <X extends Throwable> ClosingFuture<V>
catchingAsync(Class<X>
the exception type that triggers use of fallback. The exception type is matched against this step's exception. "This step's exception" means the cause of the ExecutionException thrown by Future#get() on the Future underlying this step or, if get() throws a different kind of exception, that exception itself. To avoid hiding bugs and other unrecoverable errors, callers should prefer more specific types, avoiding Throwable.class in particular.
exceptionType
,
ClosingFuture.AsyncClosingFunction<? super X, ? extends V>
the function to be called if this step fails with the expected exception type. The function's argument is this step's exception. "This step's exception" means the cause of the ExecutionException thrown by Future#get() on the Future underlying this step or, if get() throws a different kind of exception, that exception itself.
fallback
,
Executor
the executor that runs fallback if the input fails
executor
)

Returns a new ClosingFuture pipeline step derived from this one by applying a function that returns a ClosingFuture to its exception if it is an instance of a given exception type.

private <X extends Throwable, W extends V> ClosingFuture<V>
catchingAsyncMoreGeneric(Class<X> exceptionType, final ClosingFuture.AsyncClosingFunction<? super X, W> fallback, Executor executor)

private <X extends Throwable, W extends V> ClosingFuture<V>
catchingMoreGeneric(Class<X> exceptionType, final ClosingFuture.ClosingFunction<? super X, W> fallback, Executor executor)

private void
private void
private static void
closeQuietly(final AutoCloseable closeable, Executor executor)

private boolean
private <U extends @Nullable Object> ClosingFuture<U>
derive(FluentFuture<U> future)

public static <C extends @Nullable Object & @Nullable AutoCloseable> ClosingFuture<C>
eventuallyClosing(ListenableFuture<C>
the future to create the ClosingFuture from. For discussion of the future's result type C, see DeferredCloser#eventuallyClose(Object, Executor).
future
,
final Executor
the future's result will be closed on this executor
closingExecutor
)

Deprecated Creating Futures of closeable types is dangerous in general because the underlying value may never be closed if the Future is canceled after its operation begins.
Starts a ClosingFuture pipeline with a ListenableFuture.
protected void
finalize()

Overrides java.lang.Object.finalize.

Called by the garbage collector on an object when garbage collection determines that there are no more references to the object.
public FluentFuture<V>

Returns:

a Future that represents the final value or exception of the pipeline
finishToFuture
()

Marks this step as the last step in the ClosingFuture pipeline.

public void
finishToValueAndCloser(final ClosingFuture.ValueAndCloserConsumer<? super V>
a callback whose method will be called (using executor) when this operation is done
consumer
,
Executor executor)

Marks this step as the last step in the ClosingFuture pipeline.

public static <V extends @Nullable Object> ClosingFuture<V>
from(ListenableFuture<V> future)

Starts a ClosingFuture pipeline with a ListenableFuture.

private static <C extends @Nullable Object, V extends C> void
public ListenableFuture<?>
statusFuture()

Returns a future that finishes when this step does.

public static <V extends @Nullable Object> ClosingFuture<V>
submit(ClosingFuture.ClosingCallable<V> callable, Executor executor)

Starts a ClosingFuture pipeline by submitting a callable block to an executor.

public static <V extends @Nullable Object> ClosingFuture<V>
submitAsync(ClosingFuture.AsyncClosingCallable<V> callable, Executor executor)

Starts a ClosingFuture pipeline by submitting a callable block to an executor.

public String
toString()

Overrides java.lang.Object.toString.

Returns a string representation of the object.
public <U extends @Nullable Object> ClosingFuture<U>

Returns:

the derived step
transform
(final ClosingFuture.ClosingFunction<? super V, U>
transforms the value of this step to the value of the derived step
function
,
Executor
executor to run the function in
executor
)

Returns a new ClosingFuture pipeline step derived from this one by applying a function to its value.

public <U extends @Nullable Object> ClosingFuture<U>

Returns:

the derived step
transformAsync
(final ClosingFuture.AsyncClosingFunction<? super V, U>
transforms the value of this step to a ClosingFuture with the value of the derived step
function
,
Executor
executor to run the function in
executor
)

Returns a new ClosingFuture pipeline step derived from this one by applying a function that returns a ClosingFuture to its value.

public static ClosingFuture.Combiner
whenAllComplete(Iterable<? extends ClosingFuture<?>> futures)

Starts specifying how to combine ClosingFutures into a single pipeline.

public static ClosingFuture.Combiner
whenAllComplete(ClosingFuture<?> future1, ClosingFuture<?>... moreFutures)

Starts specifying how to combine ClosingFutures into a single pipeline.

public static ClosingFuture.Combiner
whenAllSucceed(Iterable<? extends ClosingFuture<?>> futures)

Starts specifying how to combine ClosingFutures into a single pipeline, assuming they all succeed.

public static <V1 extends @Nullable Object, V2 extends @Nullable Object> ClosingFuture.Combiner2<V1, V2>
whenAllSucceed(ClosingFuture<V1> future1, ClosingFuture<V2> future2)

Starts specifying how to combine two ClosingFutures into a single pipeline, assuming they all succeed.

public static <V1 extends @Nullable Object, V2 extends @Nullable Object, V3 extends @Nullable Object> ClosingFuture.Combiner3<V1, V2, V3>
whenAllSucceed(ClosingFuture<V1> future1, ClosingFuture<V2> future2, ClosingFuture<V3> future3)

Starts specifying how to combine three ClosingFutures into a single pipeline, assuming they all succeed.

public static <V1 extends @Nullable Object, V2 extends @Nullable Object, V3 extends @Nullable Object, V4 extends @Nullable Object> ClosingFuture.Combiner4<V1, V2, V3, V4>
whenAllSucceed(ClosingFuture<V1> future1, ClosingFuture<V2> future2, ClosingFuture<V3> future3, ClosingFuture<V4> future4)

Starts specifying how to combine four ClosingFutures into a single pipeline, assuming they all succeed.

public static <V1 extends @Nullable Object, V2 extends @Nullable Object, V3 extends @Nullable Object, V4 extends @Nullable Object, V5 extends @Nullable Object> ClosingFuture.Combiner5<V1, V2, V3, V4, V5>
whenAllSucceed(ClosingFuture<V1> future1, ClosingFuture<V2> future2, ClosingFuture<V3> future3, ClosingFuture<V4> future4, ClosingFuture<V5> future5)

Starts specifying how to combine five ClosingFutures into a single pipeline, assuming they all succeed.

public static ClosingFuture.Combiner
whenAllSucceed(ClosingFuture<?> future1, ClosingFuture<?> future2, ClosingFuture<?> future3, ClosingFuture<?> future4, ClosingFuture<?> future5, ClosingFuture<?> future6, ClosingFuture<?>... moreFutures)

Starts specifying how to combine ClosingFutures into a single pipeline, assuming they all succeed.

pack-priv CountDownLatch
whenClosedCountDown()

Returns an object that can be used to wait until this objects' deferred closeables have all had Runnables that close them submitted to each one's closing Executor.

public static <V extends @Nullable Object, U extends @Nullable Object> ClosingFuture.AsyncClosingFunction<V, U>
withoutCloser(final AsyncFunction<V, U>
transforms the value of a ClosingFuture step to a ListenableFuture with the value of a derived step
function
)

Returns an AsyncClosingFunction that applies an AsyncFunction to an input, ignoring the DeferredCloser and returning a ClosingFuture derived from the returned ListenableFuture.

Inherited from java.lang.Object:
cloneequalsgetClasshashCodenotifynotifyAllwaitwaitwait