http: adding an interface to inform filters of local replies#15172
http: adding an interface to inform filters of local replies#15172alyssawilk merged 11 commits intoenvoyproxy:mainfrom
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. |
goaway
left a comment
There was a problem hiding this comment.
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>
snowp
left a comment
There was a problem hiding this comment.
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.
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.
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.
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.
I mean we don't really for sendLocalReply logs either, right?
There was a problem hiding this comment.
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
| // Http::FilterChainFactoryCallbacks | ||
| void addStreamDecoderFilter(StreamDecoderFilterSharedPtr filter) override { | ||
| addStreamDecoderFilterWorker(filter, nullptr, false); | ||
| filters_.push_back(filter.get()); |
There was a problem hiding this comment.
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.
sure, added to include.
Signed-off-by: Alyssa Wilk <alyssar@chromium.org>
alyssawilk
left a comment
There was a problem hiding this comment.
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.
I mean we don't really for sendLocalReply logs either, right?
| // Http::FilterChainFactoryCallbacks | ||
| void addStreamDecoderFilter(StreamDecoderFilterSharedPtr filter) override { | ||
| addStreamDecoderFilterWorker(filter, nullptr, false); | ||
| filters_.push_back(filter.get()); |
There was a problem hiding this comment.
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.
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! |
snowp
left a comment
There was a problem hiding this comment.
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.
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"
Risk Level: low (no-op for most filters)
Testing: new integration test. NEEDS UNIT TESTS
Docs Changes: n/a
Release Notes: TBD
Fixes #14791