-
Notifications
You must be signed in to change notification settings - Fork 5.5k
filter state: add a mark for sharing with the upstream #21700
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 3 commits
1c0cf91
52bd5c7
83a8469
03318e8
7a1b3ee
218f97d
eaca9db
0c3b11f
9e5a187
cd1f7c5
7ff0070
1948a0a
643e24b
a16242b
4566981
a1fd5df
30250ba
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -26,7 +26,24 @@ using FilterStateSharedPtr = std::shared_ptr<FilterState>; | |
| */ | ||
| class FilterState { | ||
| public: | ||
| enum class StateType { ReadOnly, Mutable }; | ||
| enum StateType { | ||
|
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. I think it's simpler to just leave this as the previous enum, and add another bool for
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. When the upstream L7 filters get done, we'll also need to share with the upstream request I think. I could add another enum for sharing configuration I suppose? |
||
| // Readonly objects must be set once. | ||
| ReadOnly = 0x1, | ||
|
|
||
| // Mutable objects can be overwritten with the same state type, life span, and name. | ||
| Mutable = 0, | ||
|
|
||
| // Mark a filter state object as shared with the upstream connection. | ||
| // Shared filter state objects are copied by reference from the downstream | ||
| // requests and connections to the upstream connection filter state, and | ||
| // also participate in the hashing decisions in the transport socket | ||
| // options when connections are re-used between downstream requests. | ||
| SharedWithUpstreamConnection = 0x2, | ||
|
|
||
| // ATTENTION: MAKE SURE THIS REMAINS EQUAL TO THE LAST FLAG. | ||
| LastFlag = SharedWithUpstreamConnection, | ||
| }; | ||
|
|
||
| // Objects stored in the FilterState may have different life span. Life span is what controls | ||
| // how long an object stored in FilterState lives. Implementation of this interface actually | ||
| // stores objects in a (reverse) tree manner - multiple FilterStateImpl with shorter life span may | ||
|
|
@@ -45,6 +62,16 @@ class FilterState { | |
| // | ||
| // Note that order matters in this enum because it's assumed that life span grows as enum number | ||
| // grows. | ||
| // | ||
| // Note that for more accurate book-keeping it is recommended to subscribe to | ||
| // the stream callbacks instead of relying on the destruction of the filter | ||
| // state. | ||
| // | ||
| // As a special case, objects that are marked as shared with the upstream | ||
| // become bound to the upstream connection life span, regardless of the | ||
|
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. clarify: the object will live as long as either the downstream or upstream connection is open. The current wording implies that the lifetime is strictly tied to the upstream connection.
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. Clarified, LMK if it can be improved further. |
||
| // original life span. That means, for example, that a shared request span | ||
| // object may outlive the original request when it is shared, because it may | ||
| // be captured by an upstream connection for the original downstream request. | ||
| enum LifeSpan { FilterChain, Request, Connection, TopSpan = Connection }; | ||
|
|
||
| class Object { | ||
|
|
@@ -66,6 +93,15 @@ class FilterState { | |
| virtual absl::optional<std::string> serializeAsString() const { return absl::nullopt; } | ||
| }; | ||
|
|
||
| struct FilterObject { | ||
| std::shared_ptr<Object> data_; | ||
| FilterState::StateType state_type_; | ||
| std::string name_{""}; | ||
|
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. The initialization can just be
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. Done. |
||
| }; | ||
|
|
||
| using Objects = std::vector<FilterObject>; | ||
| using ObjectsPtr = std::unique_ptr<Objects>; | ||
|
|
||
| virtual ~FilterState() = default; | ||
|
|
||
| /** | ||
|
|
@@ -156,6 +192,11 @@ class FilterState { | |
| * either the top LifeSpan or the parent is not yet created. | ||
| */ | ||
| virtual FilterStateSharedPtr parent() const PURE; | ||
|
|
||
| /** | ||
| * @return filter objects that are shared with the upstream connection. | ||
| **/ | ||
| virtual ObjectsPtr objectsSharedWithUpstreamConnection() const PURE; | ||
| }; | ||
|
|
||
| } // namespace StreamInfo | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -6,6 +6,8 @@ | |
| #include <utility> | ||
| #include <vector> | ||
|
|
||
| #include "envoy/common/hashable.h" | ||
|
|
||
| #include "source/common/common/scalar_to_byte_vector.h" | ||
| #include "source/common/common/utility.h" | ||
| #include "source/common/network/application_protocol.h" | ||
|
|
@@ -40,6 +42,14 @@ void CommonTransportSocketFactory::hashKey(std::vector<uint8_t>& key, | |
| for (const auto& protocol : alpn_fallback) { | ||
| pushScalarToByteVector(StringUtil::CaseInsensitiveHash()(protocol), key); | ||
| } | ||
|
|
||
| for (const auto& object : options->filterStateObjects()) { | ||
| if (auto hashable = dynamic_cast<const Hashable*>(object.data_.get()); hashable != nullptr) { | ||
|
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. What happens if an object isn't
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.
|
||
| if (auto hash = hashable->hash(); hash) { | ||
| pushScalarToByteVector(hash.value(), key); | ||
| } | ||
| } | ||
| } | ||
| } | ||
|
|
||
| TransportSocketOptionsConstSharedPtr TransportSocketOptionsUtility::fromFilterState( | ||
|
|
@@ -79,7 +89,8 @@ TransportSocketOptionsConstSharedPtr TransportSocketOptionsUtility::fromFilterSt | |
|
|
||
| return std::make_shared<Network::TransportSocketOptionsImpl>( | ||
| server_name, std::move(subject_alt_names), std::move(application_protocols), | ||
| std::move(alpn_fallback), proxy_protocol_options, filter_state); | ||
| std::move(alpn_fallback), proxy_protocol_options, | ||
| filter_state->objectsSharedWithUpstreamConnection()); | ||
| } | ||
|
|
||
| } // namespace Network | ||
|
|
||
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 function name should be more descriptive, maybe something like
downstreamSharedFilterStateObjects().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.
Renamed.