Reduce object creation on Http2FrameCodec (#9333)

Motivation:

We don't need the extra ChannelPromise when writing headers anymore in Http2FrameCodec. This also means we cal re-use a ChannelFutureListener and so not need to create new instances all the time.

Modifications:

- Just pass the original ChannelPromise when writing headers
- Reuse the ChannelFutureListener

Result:

Two less objects created when writing headers for an not-yet created stream.
This commit is contained in:
Norman Maurer 2019-07-06 09:08:20 +02:00 committed by GitHub
parent 6da809dc11
commit db8dd66f09
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -159,6 +159,12 @@ public class Http2FrameCodec extends Http2ConnectionHandler {
private int numBufferedStreams; private int numBufferedStreams;
private final IntObjectMap<DefaultHttp2FrameStream> frameStreamToInitializeMap = private final IntObjectMap<DefaultHttp2FrameStream> frameStreamToInitializeMap =
new IntObjectHashMap<DefaultHttp2FrameStream>(8); new IntObjectHashMap<DefaultHttp2FrameStream>(8);
private final ChannelFutureListener bufferedStreamsListener = new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture future) throws Exception {
numBufferedStreams--;
}
};
Http2FrameCodec(Http2ConnectionEncoder encoder, Http2ConnectionDecoder decoder, Http2Settings initialSettings, Http2FrameCodec(Http2ConnectionEncoder encoder, Http2ConnectionDecoder decoder, Http2Settings initialSettings,
boolean decoupleCloseAndGoAway) { boolean decoupleCloseAndGoAway) {
@ -395,37 +401,15 @@ public class Http2FrameCodec extends Http2ConnectionHandler {
// We should not re-use ids. // We should not re-use ids.
assert old == null; assert old == null;
// TODO(buchgr): Once Http2FrameStream and Http2Stream are merged this is no longer necessary.
final ChannelPromise writePromise = ctx.newPromise();
encoder().writeHeaders(ctx, streamId, headersFrame.headers(), headersFrame.padding(), encoder().writeHeaders(ctx, streamId, headersFrame.headers(), headersFrame.padding(),
headersFrame.isEndStream(), writePromise); headersFrame.isEndStream(), promise);
if (writePromise.isDone()) { if (!promise.isDone()) {
notifyHeaderWritePromise(writePromise, promise);
} else {
numBufferedStreams++; numBufferedStreams++;
promise.addListener(bufferedStreamsListener);
writePromise.addListener(new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture future) throws Exception {
numBufferedStreams--;
notifyHeaderWritePromise(future, promise);
}
});
} }
} }
} }
private static void notifyHeaderWritePromise(ChannelFuture future, ChannelPromise promise) {
Throwable cause = future.cause();
if (cause == null) {
promise.setSuccess();
} else {
promise.setFailure(cause);
}
}
private void onStreamActive0(Http2Stream stream) { private void onStreamActive0(Http2Stream stream) {
if (stream.id() != Http2CodecUtil.HTTP_UPGRADE_STREAM_ID && if (stream.id() != Http2CodecUtil.HTTP_UPGRADE_STREAM_ID &&
connection().local().isValidStreamId(stream.id())) { connection().local().isValidStreamId(stream.id())) {
@ -512,7 +496,7 @@ public class Http2FrameCodec extends Http2ConnectionHandler {
} }
} }
void onHttp2UnknownStreamError(@SuppressWarnings("unused") ChannelHandlerContext ctx, Throwable cause, private void onHttp2UnknownStreamError(@SuppressWarnings("unused") ChannelHandlerContext ctx, Throwable cause,
Http2Exception.StreamException streamException) { Http2Exception.StreamException streamException) {
// Just log.... // Just log....
LOG.warn("Stream exception thrown for unknown stream {}.", streamException.streamId(), cause); LOG.warn("Stream exception thrown for unknown stream {}.", streamException.streamId(), cause);
@ -615,11 +599,11 @@ public class Http2FrameCodec extends Http2ConnectionHandler {
} }
} }
void onUpgradeEvent(ChannelHandlerContext ctx, UpgradeEvent evt) { private void onUpgradeEvent(ChannelHandlerContext ctx, UpgradeEvent evt) {
ctx.fireUserEventTriggered(evt); ctx.fireUserEventTriggered(evt);
} }
void onHttp2StreamWritabilityChanged(ChannelHandlerContext ctx, Http2FrameStream stream, private void onHttp2StreamWritabilityChanged(ChannelHandlerContext ctx, Http2FrameStream stream,
@SuppressWarnings("unused") boolean writable) { @SuppressWarnings("unused") boolean writable) {
ctx.fireUserEventTriggered(Http2FrameStreamEvent.writabilityChanged(stream)); ctx.fireUserEventTriggered(Http2FrameStreamEvent.writabilityChanged(stream));
} }