-
Notifications
You must be signed in to change notification settings - Fork 5.5k
Common: Introduce StopAllIteration filter status for decoding and encoding filters #5954
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
Changes from 43 commits
3835768
9cf21dd
4429d12
94c4d44
eabbeb6
0bd2315
b437b67
50b7e7c
5c9fc64
b3527f7
eaa2ceb
48a3833
ac8a553
f595c23
ee71a1f
6544a7c
3f2656b
6996475
7bf4912
119e166
82588d3
d2839d6
eb25b60
82e02e2
e0726f0
a43ba57
701493a
66ebe16
e9f387a
b7b8113
dd80759
eef5003
bcb917b
5f21a63
e691414
5dfb999
c60f2df
c645f9b
0ddb3af
beb19b8
d875ca4
e7cebab
d02d056
c2becd0
9e2e461
4ca783e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -95,16 +95,26 @@ class ConnectionManagerImpl : Logger::Loggable<Logger::Id::http>, | |
| */ | ||
| struct ActiveStreamFilterBase : public virtual StreamFilterCallbacks { | ||
| ActiveStreamFilterBase(ActiveStream& parent, bool dual_filter) | ||
| : parent_(parent), headers_continued_(false), continue_headers_continued_(false), | ||
| stopped_(false), end_stream_(false), dual_filter_(dual_filter) {} | ||
| : iteration_state_(IterationState::Continue), iterate_from_current_filter_(false), | ||
| parent_(parent), headers_continued_(false), continue_headers_continued_(false), | ||
| end_stream_(false), dual_filter_(dual_filter) {} | ||
|
|
||
| // Functions in the following block are called after the filter finishes processing | ||
| // corresponding data. Those functions handle state updates and data storage (if needed) | ||
| // according to the status returned by filter's callback functions. | ||
| bool commonHandleAfter100ContinueHeadersCallback(FilterHeadersStatus status); | ||
| bool commonHandleAfterHeadersCallback(FilterHeadersStatus status, bool& headers_only); | ||
| void commonHandleBufferData(Buffer::Instance& provided_data); | ||
| bool commonHandleAfterDataCallback(FilterDataStatus status, Buffer::Instance& provided_data, | ||
| bool& buffer_was_streaming); | ||
| bool commonHandleAfterTrailersCallback(FilterTrailersStatus status); | ||
|
|
||
| // Buffers provided_data. | ||
| void commonHandleBufferData(Buffer::Instance& provided_data); | ||
|
|
||
| // If iteration has stopped for all frame types, calls this function to buffer the data before | ||
| // the filter processes data. The function also updates streaming state. | ||
| void commonBufferDataIfStopAll(Buffer::Instance& provided_data, bool& buffer_was_streaming); | ||
|
|
||
| void commonContinue(); | ||
| virtual bool canContinue() PURE; | ||
| virtual Buffer::WatermarkBufferPtr createBuffer() PURE; | ||
|
|
@@ -128,10 +138,35 @@ class ConnectionManagerImpl : Logger::Loggable<Logger::Id::http>, | |
| Tracing::Span& activeSpan() override; | ||
| Tracing::Config& tracingConfig() override; | ||
|
|
||
| // Functions to set or get iteration state. | ||
| bool canIterate() { return iteration_state_ == IterationState::Continue; } | ||
| bool stoppedAll() { | ||
| return iteration_state_ == IterationState::StopAllBuffer || | ||
| iteration_state_ == IterationState::StopAllWatermark; | ||
| } | ||
| void allowIteration() { | ||
| ASSERT(iteration_state_ != IterationState::Continue); | ||
| iteration_state_ = IterationState::Continue; | ||
| } | ||
|
|
||
| // The state of iteration. | ||
| enum class IterationState { | ||
| Continue, // Iteration has not stopped for any frame type. | ||
| StopSingleIteration, // Iteration has stopped for headers, 100-continue, or data. | ||
| StopAllBuffer, // Iteration has stopped for all frame types, and following data should | ||
| // be buffered. | ||
| StopAllWatermark, // Iteration has stopped for all frame types, and following data should | ||
| // be buffered until high watermark is reached. | ||
| }; | ||
| IterationState iteration_state_; | ||
| // If the filter resumes iteration from a StopAllBuffer/Watermark state, the current filter | ||
| // hasn't parsed data and trailers. As a result, the filter iteration should start with the | ||
| // 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_; | ||
|
mattklein123 marked this conversation as resolved.
|
||
| ActiveStream& parent_; | ||
| bool headers_continued_ : 1; | ||
| bool continue_headers_continued_ : 1; | ||
| bool stopped_ : 1; | ||
| // If true, end_stream is called for this filter. | ||
| bool end_stream_ : 1; | ||
| const bool dual_filter_ : 1; | ||
|
|
@@ -164,7 +199,8 @@ class ConnectionManagerImpl : Logger::Loggable<Logger::Id::http>, | |
| parent_.decodeHeaders(this, *parent_.request_headers_, end_stream); | ||
| } | ||
| void doData(bool end_stream) override { | ||
| parent_.decodeData(this, *parent_.buffered_request_data_, end_stream); | ||
| parent_.decodeData(this, *parent_.buffered_request_data_, end_stream, | ||
| ActiveStream::FilterIterationStartState::Can_start_from_current); | ||
| } | ||
| void doTrailers() override { parent_.decodeTrailers(this, *parent_.request_trailers_); } | ||
| const HeaderMapPtr& trailers() override { return parent_.request_trailers_; } | ||
|
|
@@ -247,7 +283,8 @@ class ConnectionManagerImpl : Logger::Loggable<Logger::Id::http>, | |
| parent_.encodeHeaders(this, *parent_.response_headers_, end_stream); | ||
| } | ||
| void doData(bool end_stream) override { | ||
| parent_.encodeData(this, *parent_.buffered_response_data_, end_stream); | ||
| parent_.encodeData(this, *parent_.buffered_response_data_, end_stream, | ||
| ActiveStream::FilterIterationStartState::Can_start_from_current); | ||
| } | ||
| void doTrailers() override { parent_.encodeTrailers(this, *parent_.response_trailers_); } | ||
| const HeaderMapPtr& trailers() override { return parent_.response_trailers_; } | ||
|
|
@@ -290,16 +327,32 @@ class ConnectionManagerImpl : Logger::Loggable<Logger::Id::http>, | |
| ActiveStream(ConnectionManagerImpl& connection_manager); | ||
| ~ActiveStream(); | ||
|
|
||
| // Indicates which filter to start the iteration with. | ||
| enum class FilterIterationStartState { Always_start_from_next, Can_start_from_current }; | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit:
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fixed. Thanks! |
||
|
|
||
| void addStreamDecoderFilterWorker(StreamDecoderFilterSharedPtr filter, bool dual_filter); | ||
| void addStreamEncoderFilterWorker(StreamEncoderFilterSharedPtr filter, bool dual_filter); | ||
| void chargeStats(const HeaderMap& headers); | ||
| // Returns the encoder filter to start iteration with. If the function is called from a filter | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: now with the enum I think the 2nd part of this comment is obvious and can be removed, same below.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fixed. Thanks! |
||
| // that should always iterate from the next filter, set Always_start_from_next to | ||
| // filter_iteration_start_state. | ||
| std::list<ActiveStreamEncoderFilterPtr>::iterator | ||
| commonEncodePrefix(ActiveStreamEncoderFilter* filter, bool end_stream); | ||
| commonEncodePrefix(ActiveStreamEncoderFilter* filter, bool end_stream, | ||
|
mattklein123 marked this conversation as resolved.
|
||
| FilterIterationStartState filter_iteration_start_state); | ||
| // Returns the decoder filter to start iteration with. If the function is called from a filter | ||
| // that should always iterate from the next filter, set Always_start_from_next to | ||
| // filter_iteration_start_state. | ||
| std::list<ActiveStreamDecoderFilterPtr>::iterator | ||
| commonDecodePrefix(ActiveStreamDecoderFilter* filter, | ||
| FilterIterationStartState filter_iteration_start_state); | ||
| const Network::Connection* connection(); | ||
| void addDecodedData(ActiveStreamDecoderFilter& filter, Buffer::Instance& data, bool streaming); | ||
| HeaderMap& addDecodedTrailers(); | ||
| void decodeHeaders(ActiveStreamDecoderFilter* filter, HeaderMap& headers, bool end_stream); | ||
| void decodeData(ActiveStreamDecoderFilter* filter, Buffer::Instance& data, bool end_stream); | ||
| // Sends data through decoding filter chains. filter_iteration_start_state indicates which | ||
| // filter to start the iteration with. | ||
| void decodeData(ActiveStreamDecoderFilter* filter, Buffer::Instance& data, bool end_stream, | ||
| FilterIterationStartState filter_iteration_start_state); | ||
| void decodeTrailers(ActiveStreamDecoderFilter* filter, HeaderMap& trailers); | ||
| void disarmRequestTimeout(); | ||
| void maybeEndDecode(bool end_stream); | ||
|
|
@@ -311,11 +364,19 @@ class ConnectionManagerImpl : Logger::Loggable<Logger::Id::http>, | |
| const absl::optional<Grpc::Status::GrpcStatus> grpc_status); | ||
| void encode100ContinueHeaders(ActiveStreamEncoderFilter* filter, HeaderMap& headers); | ||
| void encodeHeaders(ActiveStreamEncoderFilter* filter, HeaderMap& headers, bool end_stream); | ||
| void encodeData(ActiveStreamEncoderFilter* filter, Buffer::Instance& data, bool end_stream); | ||
| // Sends data through encoding filter chains. filter_iteration_start_state indicates which | ||
| // filter to start the iteration with. | ||
| void encodeData(ActiveStreamEncoderFilter* filter, Buffer::Instance& data, bool end_stream, | ||
| FilterIterationStartState filter_iteration_start_state); | ||
| void encodeTrailers(ActiveStreamEncoderFilter* filter, HeaderMap& trailers); | ||
| void encodeMetadata(ActiveStreamEncoderFilter* filter, MetadataMapPtr&& metadata_map_ptr); | ||
| void maybeEndEncode(bool end_stream); | ||
| uint64_t streamId() { return stream_id_; } | ||
| // Returns true if filter has stopped iteration for all frame types. Otherwise, returns false. | ||
| // filter_streaming is the variable to indicate if stream is streaming, and its value may be | ||
| // changed by the function. | ||
| bool handleDataIfStopAll(ActiveStreamFilterBase& filter, Buffer::Instance& data, | ||
| bool& filter_streaming); | ||
|
|
||
| // Http::StreamCallbacks | ||
| void onResetStream(StreamResetReason reason, | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.