Don't iterate through active h2-streams if lastStreamId is MAX_VALUE (#11304)

Motivation:

Incoming `Http2GoAwayFrame#lastStreamId()` tells what was the last
streamId that the remote peer takes for processing [1]. We fire a
userEvent for all streams above that value to let users know those are
safe to retry on another connection. There is no need to go through
`forEachActiveStream` if `lastStreamId == Integer.MAX_VALUE` because
none of the streams can have id greater that MAX_VALUE.

1. https://datatracker.ietf.org/doc/html/rfc7540#section-6.8

Modifications:

- Return fast from `onHttp2GoAwayFrame` in `Http2MultiplexCodec` and
`Http2MultiplexHandler` if `lastStreamId() == Integer.MAX_VALUE`;

Result:

No unnecessary iteration over active streams on GO_AWAY if
`lastStreamId() == Integer.MAX_VALUE`.
This commit is contained in:
Idel Pivnitskiy 2021-05-26 05:05:57 -05:00 committed by Norman Maurer
parent c80d55bd7c
commit 824fe7a0eb
2 changed files with 10 additions and 1 deletions

View File

@ -215,6 +215,11 @@ public class Http2MultiplexCodec extends Http2FrameCodec {
}
private void onHttp2GoAwayFrame(ChannelHandlerContext ctx, final Http2GoAwayFrame goAwayFrame) {
if (goAwayFrame.lastStreamId() == Integer.MAX_VALUE) {
// None of the streams can have an id greater than Integer.MAX_VALUE
return;
}
// Notify which streams were not processed by the remote peer and are safe to retry on another connection:
try {
forEachActiveStream(stream -> {
final int streamId = stream.id();

View File

@ -25,7 +25,6 @@ import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.EventLoop;
import io.netty.channel.ServerChannel;
import io.netty.handler.codec.DecoderException;
import io.netty.handler.codec.http2.Http2FrameCodec.DefaultHttp2FrameStream;
import io.netty.util.ReferenceCounted;
import io.netty.util.internal.UnstableApi;
@ -293,6 +292,11 @@ public final class Http2MultiplexHandler extends Http2ChannelDuplexHandler {
}
private void onHttp2GoAwayFrame(ChannelHandlerContext ctx, final Http2GoAwayFrame goAwayFrame) {
if (goAwayFrame.lastStreamId() == Integer.MAX_VALUE) {
// None of the streams can have an id greater than Integer.MAX_VALUE
return;
}
// Notify which streams were not processed by the remote peer and are safe to retry on another connection:
try {
final boolean server = isServer(ctx);
forEachActiveStream(stream -> {