Respect ctx.read() calls while processing reads for the child channel…#8617
Conversation
|
@rschmitt FYI... this should fix your problem. Thanks again for the reproducer. |
| assert next == null && previous == null; | ||
| readInProgress = false; | ||
| if (readStatus == ReadStatus.REQUESTED) { | ||
| readStatus = ReadStatus.IN_PROGRESS; |
There was a problem hiding this comment.
Are you sure this is all you have to do? If auto-read is disabled on the parent channel, might you not have to request a read to ensure progress? (This may happen somewhere else, but I can't see where.)
There was a problem hiding this comment.
@rschmitt that is a different "issue" and I am not even sure if we should do anything here at all by default. You could easily add a ChannelOutboundHandler to the ChannelPipeline of the Channel which will trigger channel.parent().read() when a read is received.
There was a problem hiding this comment.
We could also make this a ChannelOption on the "child channel".
There was a problem hiding this comment.
Just to give some more background why I think we should not handle this by default... I think the user may want to handle the read pattern / back pressure independently in some cases.
There was a problem hiding this comment.
If this is the philosophy behind this class, then I have no idea why my current h2 server works, because it only reads from the parent channel one time (right at the end of initChannel), and autoread is constantly disabled on both parent and child streams.
There was a problem hiding this comment.
I will investigate once this one is pulled in... Like I said I think these are different "concerns".
There was a problem hiding this comment.
@rschmitt now that this one is merged I will check your other concern during this week.
| * {@link RecvByteBufAllocator} behavior a read may extend beyond the {@link Http2ChannelUnsafe#beginRead()} | ||
| * method scope. The {@link Http2ChannelUnsafe#beginRead()} loop may drain all pending data, and then if the | ||
| * parent channel is reading this channel may still accept frames. | ||
| * This variable represents if a read is in progress for the current channe or was requested. |
| ReferenceCountUtil.release(frame); | ||
| } else if (readInProgress) { | ||
| } else if (readStatus != ReadStatus.IDLE) { | ||
| // If readInProgress there cannot be anything in the queue, otherwise we would have drained it from the |
There was a problem hiding this comment.
"If a read is in progress or has been requested, there cannot be anything in the queue" (etc)
…s when using the Http2MultiplexCodec. Motivation: We did not correct respect ctx.read() calls while processing a read for a child Channel. This could lead to read stales when auto read is disabled and no other read was requested. Modifications: - Keep track of extra read() calls while processing reads - Add unit tests that verify that read() is respected when triggered either in channelRead(...) or channelReadComplete(...) Result: Fixes #8209.
b30f230 to
79816d9
Compare
…s when using the Http2MultiplexCodec. (#8617) Motivation: We did not correct respect ctx.read() calls while processing a read for a child Channel. This could lead to read stales when auto read is disabled and no other read was requested. Modifications: - Keep track of extra read() calls while processing reads - Add unit tests that verify that read() is respected when triggered either in channelRead(...) or channelReadComplete(...) Result: Fixes #8209.
|
Code LGTM |
| void fireChildReadComplete() { | ||
| assert eventLoop().inEventLoop(); | ||
| assert readInProgress; | ||
| assert readStatus == ReadStatus.IN_PROGRESS; |
There was a problem hiding this comment.
Is this still accurate? If the user had requested a read while in the IN_PROGRESS state I think we transition to the REQUESTED state. In fact, the unsafe.notifyReadComplete call right after the assert will check if we're in the REQUESTED state and transition back to IN_PROGRESS.
There was a problem hiding this comment.
@bryce-anderson I think you are right... it should be either IN_PROGRESS or REQUESTED. Let me fix this.
…s when using the Http2MultiplexCodec.
Motivation:
We did not correct respect ctx.read() calls while processing a read for a child Channel. This could lead to read stales when auto read is disabled and no other read was requested.
Modifications:
Result:
Fixes #8209.