-
Notifications
You must be signed in to change notification settings - Fork 4.9k
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
http: adding an interface to inform filters of local replies #15172
Conversation
Signed-off-by: Alyssa Wilk <alyssar@chromium.org>
Hey @goaway WDYT of this as a start? Looking for high level suggestions (do we need other return options? more data in the struct? better naming?) and once I have your thumbs up I'll add unit tests and send it to the maintainers for review. |
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.
Wow, thank you for putting something together so quickly! This looks great, and I do think it gives us everything we need.
I don't immediately see a need for any extra data; we surface errors with an error code and a message, which has a direct corollary to the HTTP status code and body. The only thing I wonder is if introducing a different raiseStreamError
interface might allow for more nuanced status codes than what HTTP affords in some cases.
But that also seems like something we could consider separately - today we map HTTP code to an error code anyways so this would still be a big improvement for us.
Signed-off-by: Alyssa Wilk <alyssar@chromium.org>
Signed-off-by: Alyssa Wilk <alyssar@chromium.org>
ping! |
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.
Thanks this looks pretty good and not too complicated.
Curious what you think about @goaway's suggestion of an error API that would allow us to semantically differentiate a local reply used as a helper to respond (e.g. https://github.com/envoyproxy/envoy/blob/main/source/extensions/filters/http/health_check/health_check.cc#L179-L186) vs stream errors (https://github.com/envoyproxy/envoy/blob/main/source/common/router/router.cc#L659-L661).
I think this could probably be solved by just having a bool streamError() const
on StreamInfo and having a wrapper around sendLocalReply that sets this value for the error cases, but curious if you think it's worth integrating this into the onLocalReply API more tightly.
// Continue sending onLocalReply to all filters, but reset the stream once all filters have been | ||
// informed rather than sending the local reply. |
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.
Should we have some way of indicating to filters that the local reply is going to be reset? I can imagine filters wanting to do some mutation of the local reply in some cases, but it doesn't make sense for them to do this if a previous filter has triggered a reset
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.
they can't mutate the local reply here, only from the actual sendlocalReply, but can't hurt to pass on that info
ENVOY_STREAM_LOG(debug, "Resetting stream due to {}. onLocalReply requested reset.", *this, | ||
details); |
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.
Any way we can capture which filter is triggering the reset? Or let the filter that triggers a reset include information?
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.
I mean we don't really for sendLocalReply logs either, right?
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.
At least with local replies we can infer it from the response code details, but yea I don't think this is necessary, just a nice to have
@@ -760,6 +760,7 @@ class FilterManager : public ScopeTrackedObject, | |||
// Http::FilterChainFactoryCallbacks | |||
void addStreamDecoderFilter(StreamDecoderFilterSharedPtr filter) override { | |||
addStreamDecoderFilterWorker(filter, nullptr, false); | |||
filters_.push_back(filter.get()); |
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.
Should we document the order in which filters are given the callback? Seems like the order is first added to last added, regardless of whether it was a decoder or encoder filter. I think people might intuitively expect this to follow the decoder or encoder filter chains, but currently this can interleave between the two.
I think with the current impl the order doesn't matter at all, but I can imagine iterations of this feature (like my suggestion of capturing information about which filter is doing the reset) where it starts mattering.
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.
sure, added to include.
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.
I think this is what @goaway described at the mobile meeting. We could always make the hcm sendLocalReply be an overridable function and have envoy mobile override it, but I think there was some desire to have filters be informed that a reply is imminent, without actually sending the reply. There's also the complexities of sendLocalReply usually generating a reply but sometimes doing direct-encode or rst where I think this results in a simpler and harder-to-screw-up interface. I'm up for whatever though :-)
ENVOY_STREAM_LOG(debug, "Resetting stream due to {}. onLocalReply requested reset.", *this, | ||
details); |
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.
I mean we don't really for sendLocalReply logs either, right?
@@ -760,6 +760,7 @@ class FilterManager : public ScopeTrackedObject, | |||
// Http::FilterChainFactoryCallbacks | |||
void addStreamDecoderFilter(StreamDecoderFilterSharedPtr filter) override { | |||
addStreamDecoderFilterWorker(filter, nullptr, false); | |||
filters_.push_back(filter.get()); |
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.
sure, added to include.
// Continue sending onLocalReply to all filters, but reset the stream once all filters have been | ||
// informed rather than sending the local reply. |
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.
they can't mutate the local reply here, only from the actual sendlocalReply, but can't hurt to pass on that info
Just to clarify - the ability to override sendLocalReply or some antecedent call was mostly just a suggestion about one possible approach. I think the approach here works great though - the main requirement is to have an unambiguous signal that filters get to see regardless of whether a local reply ends up traversing the filter chain. |
Signed-off-by: Alyssa Wilk <alyssar@chromium.org>
@snowp the mac failure is the known timeout, and other comments addressed. PTAL when you get a chance! |
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.
LGTM besides the one comment comment
include/envoy/http/filter.h
Outdated
* This will be called on both encoder and decoder filters starting at the | ||
* router filter and working towards the first filter configured. |
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.
In theory someone could be using another terminal filter that isn't the router filter and still make use of local replies right? Maybe make this "at the terminal filter"
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!
Risk Level: low (no-op for most filters)
Testing: new integration test. NEEDS UNIT TESTS
Docs Changes: n/a
Release Notes: TBD
Fixes #14791