-
Notifications
You must be signed in to change notification settings - Fork 4.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
http2: fixing a (known) potential stall in the filter chain for H2 #7093
Conversation
Signed-off-by: Alyssa Wilk <alyssar@chromium.org>
Alternately we could always just create the buffer on returning StopIterationNoBuffer, but that felt higher risk |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for fixing this long standing issue. A few questions.
/wait
@@ -164,6 +164,9 @@ class ConnectionManagerImpl : Logger::Loggable<Logger::Id::http>, | |||
// current filter instead of the next one. If true, filter iteration starts with the current | |||
// filter. Otherwise, starts with the next filter in the chain. | |||
bool iterate_from_current_filter_; | |||
// Tracks if the stream end has been sent with an encode/decodeData call, to handle the case | |||
// where commonContinue is called with the only information being a terminal fin. | |||
bool end_stream_sent_with_data_; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we add this bool to the bitfield below? IIRC the reason the one above isn't in it is because it needs to be passed by address somewhere.
doData(complete() && !trailers()); | ||
// Make sure we handle filters returning StopIterationNoBuffer and then commonContinue by tracking | ||
// if the terminal fin has already been proxied. | ||
bool end_stream_with_data = complete() && !trailers(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: const
// buffer but encode/decodeData expects the buffer to exist, so create one. | ||
bufferedData() = createBuffer(); | ||
} | ||
end_stream_sent_with_data_ = true; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry why do we need the member variable? Can't we just compute this locally and then decide whether to create the buffer or not?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My concern was there might be some case with StopAllIIteration where we might end up relaying the FIN twice. if you're confident that commonDecodePrefix will pick up the right filter (which theoretically it ought to when bodies are present, so ought to when they're absent?) I'm fine nixing the local state.
Signed-off-by: Alyssa Wilk <alyssar@chromium.org>
Signed-off-by: Alyssa Wilk <alyssar@chromium.org>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Very nice. Thanks for the integration test! LGTM.
Fixing a bug where if pausing with StopIterationNoBuffer, continuing with fin-only payload wouldn't result in the filter chain continuing.
Risk Level: High (tweak to the HCM)
Testing: new integration test
Docs Changes: n/a
Release Notes: n/a