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 GitHub
parent bfd2c5ac8a
commit cb1b3517dc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 10 additions and 1 deletions

View File

@ -213,6 +213,11 @@ public class Http2MultiplexCodec extends Http2FrameCodec {
} }
private void onHttp2GoAwayFrame(ChannelHandlerContext ctx, final Http2GoAwayFrame goAwayFrame) { 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 { try {
forEachActiveStream(new Http2FrameStreamVisitor() { forEachActiveStream(new Http2FrameStreamVisitor() {
@Override @Override

View File

@ -25,7 +25,6 @@ import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelPipeline; import io.netty.channel.ChannelPipeline;
import io.netty.channel.EventLoop; import io.netty.channel.EventLoop;
import io.netty.channel.ServerChannel; import io.netty.channel.ServerChannel;
import io.netty.handler.codec.DecoderException;
import io.netty.handler.codec.http2.Http2FrameCodec.DefaultHttp2FrameStream; import io.netty.handler.codec.http2.Http2FrameCodec.DefaultHttp2FrameStream;
import io.netty.util.ReferenceCounted; import io.netty.util.ReferenceCounted;
import io.netty.util.internal.ObjectUtil; import io.netty.util.internal.ObjectUtil;
@ -298,6 +297,11 @@ public final class Http2MultiplexHandler extends Http2ChannelDuplexHandler {
} }
private void onHttp2GoAwayFrame(ChannelHandlerContext ctx, final Http2GoAwayFrame goAwayFrame) { 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 { try {
final boolean server = isServer(ctx); final boolean server = isServer(ctx);
forEachActiveStream(new Http2FrameStreamVisitor() { forEachActiveStream(new Http2FrameStreamVisitor() {