-
- All Known Subinterfaces:
ChannelGroupFuture
,RunnableFuture<V>
,RunnableScheduledFuture<V>
- All Known Implementing Classes:
DefaultPromise
public interface Future<V>
The result of an asynchronous operation.An asynchronous operation is one that might be completed outside a given thread of execution. The operation can either be performing computation, or I/O, or both.
All I/O operations in Netty are asynchronous. It means any I/O calls will return immediately with no guarantee that the requested I/O operation has been completed at the end of the call. Instead, you will be returned with a
Future
instance which gives you the information about the result or status of the I/O operation.A
Future
is either uncompleted or completed. When an I/O operation begins, a new future object is created. The new future is uncompleted initially - it is neither succeeded, failed, nor cancelled because the I/O operation is not finished yet. If the I/O operation is finished either successfully, with failure, or by cancellation, the future is marked as completed with more specific information, such as the cause of the failure. Please note that even failure and cancellation belong to the completed state.+---------------------------+ | Completed successfully | +---------------------------+ +----> isDone() = true | +--------------------------+ | | isSuccess() = true | | Uncompleted | | +===========================+ +--------------------------+ | | Completed with failure | | isDone() = false | | +---------------------------+ | isSuccess() = false |----+----> isDone() = true | | isCancelled() = false | | | cause() = non-null | | cause() = throws | | +===========================+ | getNow() = throws | | | Completed by cancellation | +--------------------------+ | +---------------------------+ +----> isDone() = true | | isCancelled() = true | +---------------------------+
Various methods are provided to let you check if the I/O operation has been completed, wait for the completion, and retrieve the result of the I/O operation. It also allows you to add
FutureListener
s so you can get notified when the I/O operation is completed.Prefer
addListener(FutureListener)
toFutureCompletionStage.await()
It is recommended to prefer
addListener(FutureListener)
, oraddListener(Object, FutureContextListener)
, toFutureCompletionStage.await()
wherever possible to get notified when an I/O operation is done and to do any follow-up tasks.The
addListener(FutureListener)
method is non-blocking. It simply adds the specifiedFutureListener
to theFuture
, and the I/O thread will notify the listeners when the I/O operation associated with the future is done. TheFutureListener
andFutureContextListener
callbacks yield the best performance and resource utilization because it does not block at all, but it could be tricky to implement a sequential logic if you are not used to event-driven programming.By contrast,
FutureCompletionStage.await()
is a blocking operation. Once called, the caller thread blocks until the operation is done. It is easier to implement a sequential logic withFutureCompletionStage.await()
, but the caller thread blocks unnecessarily until the I/O operation is done and there's relatively expensive cost of inter-thread notification. Moreover, there's a chance of deadlock in a particular circumstance, which is described below.Do not call
FutureCompletionStage.await()
inside aChannelHandler
The event handler methods in
ChannelHandler
are usually called by an I/O thread. IfFutureCompletionStage.await()
is called by an event handler method, which is called by the I/O thread, the I/O operation it is waiting for might never complete becauseFutureCompletionStage.await()
can block the I/O operation it is waiting for, which is a deadlock.// BAD - NEVER DO THIS
@Override
public void channelRead(ChannelHandlerContext
ctx, Object msg) {Future
future = ctx.channel().close(); future.asStage().await(); // Perform post-closure operation // ... } // GOOD@Override
public void channelRead(ChannelHandlerContext
ctx, Object msg) {Future
future = ctx.channel().close(); future.addListener(newFutureListener
() { public void operationComplete(Future
future) { // Perform post-closure operation // ... } }); }In spite of the disadvantages mentioned above, there are certainly the cases where it is more convenient to call
FutureCompletionStage.await()
. In such a case, please make sure you do not callFutureCompletionStage.await()
in an I/O thread. Otherwise,BlockingOperationException
will be raised to prevent a deadlock.Do not confuse I/O timeout and await timeout
The timeout value you specify with
FutureCompletionStage.await(long, TimeUnit)
is not related to the I/O timeout at all. If an I/O operation times out, the future will be marked as 'completed with failure,' as depicted in the diagram above. For example, connect timeout should be configured via a transport-specific option:// BAD - NEVER DO THIS
Bootstrap
b = ...;Future
f = b.connect(...); f.asStage().await(10, TimeUnit.SECONDS); if (f.isCancelled()) { // Connection attempt cancelled by user } else if (!f.isSuccess()) { // You might get a NullPointerException here because the future // might not be completed yet. f.cause().printStackTrace(); } else { // Connection established successfully } // GOODBootstrap
b = ...; // Configure the connect timeout option. b.option(ChannelOption
.CONNECT_TIMEOUT_MILLIS, 10000);Future
f = b.connect(...); f.asStage().await(); // Now we are sure the future is completed. assert f.isDone(); if (f.isCancelled()) { // Connection attempt cancelled by user } else if (!f.isSuccess()) { f.cause().printStackTrace(); } else { // Connection established successfully }
-
-
Method Summary
All Methods Instance Methods Abstract Methods Default Methods Modifier and Type Method Description <C> Future<V>
addListener(C context, FutureContextListener<? super C,? super V> listener)
Adds the specified listener to this future.Future<V>
addListener(FutureListener<? super V> listener)
Adds the specified listener to this future.FutureCompletionStage<V>
asStage()
Returns aFutureCompletionStage
that reflects the state of thisFuture
and so will receive all updates as well.boolean
cancel()
Cancel this asynchronous operation, unless it has already been completed or is not cancellable.default Future<V>
cascadeTo(Promise<? super V> promise)
Throwable
cause()
Returns the cause of the failed operation if the operation has failed.EventExecutor
executor()
default <R> Future<R>
flatMap(Function<V,Future<R>> mapper)
V
getNow()
Return the successful result of this asynchronous operation, if any.boolean
isCancellable()
Returnstrue
if and only if the operation can be cancelled viacancel()
.boolean
isCancelled()
Returntrue
if this operation has been cancelled.boolean
isDone()
Returntrue
if this operation has been completed either successfully, unsuccessfully, or through cancellation.boolean
isFailed()
Returnstrue
if and only if the operation was completed and failed.boolean
isSuccess()
Returnstrue
if and only if the operation was completed successfully.default <R> Future<R>
map(Function<V,R> mapper)
-
-
-
Method Detail
-
addListener
Future<V> addListener(FutureListener<? super V> listener)
Adds the specified listener to this future. The specified listener is notified when this future is done. If this future is already completed, the specified listener is notified immediately.- Parameters:
listener
- The listener to be called when this future completes. The listener will be passed this future as an argument.- Returns:
- this future object.
-
addListener
<C> Future<V> addListener(C context, FutureContextListener<? super C,? super V> listener)
Adds the specified listener to this future. The specified listener is notified when this future is done. If this future is already completed, the specified listener is notified immediately.- Parameters:
context
- The context object that will be passed to the listener when this future completes.listener
- The listener to be called when this future completes. The listener will be passed the given context, and this future.- Returns:
- this future object.
-
asStage
FutureCompletionStage<V> asStage()
Returns aFutureCompletionStage
that reflects the state of thisFuture
and so will receive all updates as well.The returned
FutureCompletionStage
also implements the JDKFuture
, and has blocking methods not found on the NettyFuture
interface, for awaiting the completion.
-
map
default <R> Future<R> map(Function<V,R> mapper)
Creates a newFuture
that will complete with the result of thisFuture
mapped through the given mapper function.If this future fails, then the returned future will fail as well, with the same exception. Cancellation of either future will cancel the other. If the mapper function throws, the returned future will fail, but this future will be unaffected.
- Type Parameters:
R
- The result type of the mapper function, and of the returned future.- Parameters:
mapper
- The function that will convert the result of this future into the result of the returned future.- Returns:
- A new future instance that will complete with the mapped result of this future.
-
flatMap
default <R> Future<R> flatMap(Function<V,Future<R>> mapper)
Creates a newFuture
that will complete with the result of thisFuture
flat-mapped through the given mapper function.The "flat" in "flat-map" means the given mapper function produces a result that itself is a future-of-R, yet this method also returns a future-of-R, rather than a future-of-future-of-R. In other words, if the same mapper function was used with the
map(Function)
method, you would get back aFuture<Future<R>>
. These nested futures are "flattened" into aFuture<R>
by this method.Effectively, this method behaves similar to this serial code, except asynchronously and with proper exception and cancellation handling:
V x = future.sync().getNow(); Future<R> y = mapper.apply(x); R result = y.sync().getNow();
If the given future fails, then the returned future will fail as well, with the same exception. Cancellation of either future will cancel the other. If the mapper function throws, the returned future will fail, but this future will be unaffected.
- Type Parameters:
R
- The result type of the mapper function, and of the returned future.- Parameters:
mapper
- The function that will convert the result of this future into the result of the returned future.- Returns:
- A new future instance that will complete with the mapped result of this future.
-
cascadeTo
default Future<V> cascadeTo(Promise<? super V> promise)
Link theFuture
andPromise
such that if theFuture
completes thePromise
will be notified. Cancellation is propagated both ways such that if theFuture
is cancelled thePromise
is cancelled and vice-versa.- Parameters:
promise
- thePromise
which will be notified- Returns:
- itself
-
cancel
boolean cancel()
Cancel this asynchronous operation, unless it has already been completed or is not cancellable.A cancelled operation is considered to be done and failed.
If the cancellation was successful, the result of this operation will be that it has failed with a
CancellationException
.Cancellation will not cause any threads working on the operation to be interrupted.
- Returns:
true
if the operation was cancelled by this call, otherwisefalse
.
-
isSuccess
boolean isSuccess()
Returnstrue
if and only if the operation was completed successfully.
-
isFailed
boolean isFailed()
Returnstrue
if and only if the operation was completed and failed.
-
isCancelled
boolean isCancelled()
Returntrue
if this operation has been cancelled.- Returns:
true
if this operation has been cancelled, otherwisefalse
.
-
isDone
boolean isDone()
Returntrue
if this operation has been completed either successfully, unsuccessfully, or through cancellation.- Returns:
true
if this operation has completed, otherwisefalse
.
-
isCancellable
boolean isCancellable()
Returnstrue
if and only if the operation can be cancelled viacancel()
. Note that this is inherently racy, as the operation could be made uncancellable at any time.- Returns:
true
if this operation can be cancelled.
-
getNow
V getNow()
Return the successful result of this asynchronous operation, if any. If the operation has not yet been completed, then this will throwIllegalStateException
. If the operation has been cancelled or failed with an exception, then this returnsnull
. Note that asynchronous operations can also be completed successfully with anull
result.- Returns:
- the result of this operation, if completed successfully.
- Throws:
IllegalStateException
- if thisFuture
orPromise
has not completed yet.
-
cause
Throwable cause()
Returns the cause of the failed operation if the operation has failed.- Returns:
- The cause of the failure, if any. Otherwise
null
if succeeded. - Throws:
IllegalStateException
- if thisPromise
has not completed yet.
-
executor
EventExecutor executor()
-
-