-
- 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
Futureinstance which gives you the information about the result or status of the I/O operation.A
Futureis 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
FutureListeners 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 specifiedFutureListenerto theFuture, and the I/O thread will notify the listeners when the I/O operation associated with the future is done. TheFutureListenerandFutureContextListenercallbacks 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 aChannelHandlerThe event handler methods in
ChannelHandlerare 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
@Overridepublic void channelRead(ChannelHandlerContextctx, Object msg) {Futurefuture = ctx.channel().close(); future.asStage().await(); // Perform post-closure operation // ... } // GOOD@Overridepublic void channelRead(ChannelHandlerContextctx, Object msg) {Futurefuture = ctx.channel().close(); future.addListener(newFutureListener() { public void operationComplete(Futurefuture) { // 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,BlockingOperationExceptionwill 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
Bootstrapb = ...;Futuref = 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 } // GOODBootstrapb = ...; // Configure the connect timeout option. b.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 10000);Futuref = 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 aFutureCompletionStagethat reflects the state of thisFutureand so will receive all updates as well.booleancancel()Cancel this asynchronous operation, unless it has already been completed or is not cancellable.default Future<V>cascadeTo(Promise<? super V> promise)Throwablecause()Returns the cause of the failed operation if the operation has failed.EventExecutorexecutor()default <R> Future<R>flatMap(Function<V,Future<R>> mapper)VgetNow()Return the successful result of this asynchronous operation, if any.booleanisCancellable()Returnstrueif and only if the operation can be cancelled viacancel().booleanisCancelled()Returntrueif this operation has been cancelled.booleanisDone()Returntrueif this operation has been completed either successfully, unsuccessfully, or through cancellation.booleanisFailed()Returnstrueif and only if the operation was completed and failed.booleanisSuccess()Returnstrueif 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 aFutureCompletionStagethat reflects the state of thisFutureand so will receive all updates as well.The returned
FutureCompletionStagealso implements the JDKFuture, and has blocking methods not found on the NettyFutureinterface, for awaiting the completion.
-
map
default <R> Future<R> map(Function<V,R> mapper)
Creates a newFuturethat will complete with the result of thisFuturemapped 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 newFuturethat will complete with the result of thisFutureflat-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 theFutureandPromisesuch that if theFuturecompletes thePromisewill be notified. Cancellation is propagated both ways such that if theFutureis cancelled thePromiseis cancelled and vice-versa.- Parameters:
promise- thePromisewhich 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:
trueif the operation was cancelled by this call, otherwisefalse.
-
isSuccess
boolean isSuccess()
Returnstrueif and only if the operation was completed successfully.
-
isFailed
boolean isFailed()
Returnstrueif and only if the operation was completed and failed.
-
isCancelled
boolean isCancelled()
Returntrueif this operation has been cancelled.- Returns:
trueif this operation has been cancelled, otherwisefalse.
-
isDone
boolean isDone()
Returntrueif this operation has been completed either successfully, unsuccessfully, or through cancellation.- Returns:
trueif this operation has completed, otherwisefalse.
-
isCancellable
boolean isCancellable()
Returnstrueif 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:
trueif 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 anullresult.- Returns:
- the result of this operation, if completed successfully.
- Throws:
IllegalStateException- if thisFutureorPromisehas 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
nullif succeeded. - Throws:
IllegalStateException- if thisPromisehas not completed yet.
-
executor
EventExecutor executor()
-
-