HTTP/2 ConnectionHandler close cleanup

Motiviation:
The connection handler stream close operation is unconditionally adding a listener object to a future. We may not have to add a listener at all because the future has already been completed.

Modifications:
- If the future is done, directly invoke the logic without creating/adding a new listener.

Result:
No need to create/add listener if the future is already done in close logic.
This commit is contained in:
Scott Mitchell 2015-05-29 16:27:59 -07:00
parent 82e580dc7f
commit 2449760ea3

View File

@ -442,20 +442,16 @@ public class Http2ConnectionHandler extends ByteToMessageDecoder implements Http
public void closeStream(final Http2Stream stream, ChannelFuture future) {
stream.close();
future.addListener(new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture future) throws Exception {
// If this connection is closing and the graceful shutdown has completed, close the connection
// once this operation completes.
if (closeListener != null && isGracefulShutdownComplete()) {
ChannelFutureListener closeListener = Http2ConnectionHandler.this.closeListener;
// This method could be called multiple times
// and we don't want to notify the closeListener multiple times.
Http2ConnectionHandler.this.closeListener = null;
closeListener.operationComplete(future);
if (future.isDone()) {
checkCloseConnection(future);
} else {
future.addListener(new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture future) throws Exception {
checkCloseConnection(future);
}
}
});
});
}
}
/**
@ -584,6 +580,26 @@ public class Http2ConnectionHandler extends ByteToMessageDecoder implements Http
}
}
/**
* Closes the connection if the graceful shutdown process has completed.
* @param future Represents the status that will be passed to the {@link #closeListener}.
*/
private void checkCloseConnection(ChannelFuture future) {
// If this connection is closing and the graceful shutdown has completed, close the connection
// once this operation completes.
if (closeListener != null && isGracefulShutdownComplete()) {
ChannelFutureListener closeListener = Http2ConnectionHandler.this.closeListener;
// This method could be called multiple times
// and we don't want to notify the closeListener multiple times.
Http2ConnectionHandler.this.closeListener = null;
try {
closeListener.operationComplete(future);
} catch (Exception e) {
throw new IllegalStateException("Close listener threw an unexpected exception", e);
}
}
}
/**
* Gets the initial settings to be sent to the remote endpoint.
*/