- NEVER DO THIS {@code @Override}public void messageReceived( {@link ChannelHandlerContext} ctx, GoodByeMessage msg) {{@link ChannelFuture} future = ctx.channel().close();future.awaitUninterruptibly(); // Perform post-closure operation // ... } // GOOD {@code @Override}public void messageReceived( {@link ChannelHandlerContext} ctx, GoodByeMessage msg) {{@link ChannelFuture} future = ctx.channel().close();future.addListener(new {@link ChannelFutureListener}() { public void operationComplete( {@link ChannelFuture} future) {// Perform post-closure operation // ... } }); }
In spite of the disadvantages mentioned above, there are certainly the cases where it is more convenient to call {@link #await()}. In such a case, please make sure you do not call {@link #await()} in an I/O thread. Otherwise,{@link BlockingOperationException} will be raised to prevent a dead lock.
Do not confuse I/O timeout and await timeout
The timeout value you specify with {@link #await(long)}, {@link #await(long,TimeUnit)}, {@link #awaitUninterruptibly(long)}, or {@link #awaitUninterruptibly(long,TimeUnit)} are not related with I/Otimeout 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 {@link Bootstrap} b = ...;{@link ChannelFuture} f = b.connect(...);f.awaitUninterruptibly(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.getCause().printStackTrace(); } else { // Connection established successfully } // GOOD {@link Bootstrap} b = ...;// Configure the connect timeout option. b.setOption( {@link ChannelOption}.CONNECT_TIMEOUT_MILLIS, 10000); {@link ChannelFuture} f = b.connect(...);f.awaitUninterruptibly(); // Now we are sure the future is completed. assert f.isDone(); if (f.isCancelled()) { // Connection attempt cancelled by user } else if (!f.isSuccess()) { f.getCause().printStackTrace(); } else { // Connection established successfully }