-
Notifications
You must be signed in to change notification settings - Fork 5.3k
On demand loading of ScopedRouteConfiguration #12640
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 all commits
ef08270
c3d39db
7f93c95
88704aa
71d9526
1fb167f
3cb0a1c
399ad9b
2e5eccc
477dc6b
abd354b
25f487d
ab60437
ae188bf
7353474
3ce3677
d54fc36
6588bf2
6cca147
f05c622
9626719
3f23c10
b2e3e1f
2564425
7c4d74d
8a641f2
c65f4b7
1aeb72b
f941ea4
74f8c29
346ff81
a4153af
16aa77e
44d5c29
3dcfa02
041bc98
874e4d3
67734d8
eddcd6d
8f40eb2
45e633c
d56f1bc
e08c201
b9dc81f
71b7a1b
e4e7a51
d9affce
896f52a
826ef9d
e1e1e74
44cb868
d8c3552
62cb93f
6d3f7f0
d26f173
6a46ebb
d78d733
70ec602
d60da44
ae7f157
1da611e
f867e53
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,15 +1,21 @@ | ||
| .. _config_http_filters_on_demand: | ||
|
|
||
| On-demand VHDS Updates | ||
|
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. |
||
| ====================== | ||
| On-demand VHDS and S/RDS Updates | ||
| ================================ | ||
|
|
||
| The on-demand VHDS filter is used to request a :ref:`virtual host <envoy_v3_api_msg_config.route.v3.VirtualHost>` | ||
| The on demand filter can be used to support either on demand VHDS or S/RDS update if configured in the filter chain. | ||
|
|
||
| The on-demand update filter can be used to request a :ref:`virtual host <envoy_v3_api_msg_config.route.v3.VirtualHost>` | ||
htuch marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| data if it's not already present in the :ref:`Route Configuration <envoy_v3_api_msg_config.route.v3.RouteConfiguration>`. The | ||
| contents of the *Host* or *:authority* header is used to create the on-demand request. For an on-demand | ||
| request to be created, :ref:`VHDS <envoy_v3_api_field_config.route.v3.RouteConfiguration.vhds>` must be enabled and either *Host* | ||
| or *:authority* header be present. | ||
|
|
||
| On-demand VHDS cannot be used with SRDS at this point. | ||
| The on-demand update filter can also be used to request a *Route Configuration* data if RouteConfiguration is specified to be | ||
| loaded on demand in the :ref:`Scoped RouteConfiguration <envoy_v3_api_msg_config.route.v3.ScopedRouteConfiguration>`. | ||
| The contents of the HTTP header is used to find the scope and create the on-demand request. | ||
|
|
||
| On-demand VHDS and on-demand S/RDS can not be used at the same time at this point. | ||
|
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. Do you have a tracking issue yet for converging the two?
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. I guess not.
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. Recommend adding one. |
||
|
|
||
| Configuration | ||
| ------------- | ||
|
|
||
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -8,6 +8,77 @@ | |
| namespace Envoy { | ||
| namespace Router { | ||
|
|
||
| /** | ||
| * Scope key fragment base class. | ||
| */ | ||
| class ScopeKeyFragmentBase { | ||
| public: | ||
| bool operator!=(const ScopeKeyFragmentBase& other) const { return !(*this == other); } | ||
|
|
||
| bool operator==(const ScopeKeyFragmentBase& other) const { | ||
| if (typeid(*this) == typeid(other)) { | ||
| return hash() == other.hash(); | ||
| } | ||
| return false; | ||
| } | ||
| virtual ~ScopeKeyFragmentBase() = default; | ||
|
|
||
| // Hash of the fragment. | ||
| virtual uint64_t hash() const PURE; | ||
| }; | ||
|
|
||
| /** | ||
| * Scope Key is composed of non-null fragments. | ||
| **/ | ||
| class ScopeKey { | ||
| public: | ||
| ScopeKey() = default; | ||
| ScopeKey(ScopeKey&& other) = default; | ||
|
|
||
| // Scopekey is not copy-assignable and copy-constructible as it contains unique_ptr inside itself. | ||
| ScopeKey(const ScopeKey&) = delete; | ||
| ScopeKey operator=(const ScopeKey&) = delete; | ||
|
|
||
| // Caller should guarantee the fragment is not nullptr. | ||
| void addFragment(std::unique_ptr<ScopeKeyFragmentBase>&& fragment) { | ||
| ASSERT(fragment != nullptr, "null fragment not allowed in ScopeKey."); | ||
| updateHash(*fragment); | ||
| fragments_.emplace_back(std::move(fragment)); | ||
| } | ||
|
|
||
| uint64_t hash() const { return hash_; } | ||
| bool operator!=(const ScopeKey& other) const; | ||
| bool operator==(const ScopeKey& other) const; | ||
|
|
||
| private: | ||
| // Update the key's hash with the new fragment hash. | ||
|
Contributor
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. why we have these diffs?
Contributor
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. nvm, I see the move later now.
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. Arguably we should split this into interface/implementation, since there is a lot of low-level implementation logic here. We have precedence for doing it this way in some cases, e.g. header map, but strongly prefer to not put a ton of implementation logic (e.g. the hash function below) inside |
||
| void updateHash(const ScopeKeyFragmentBase& fragment) { | ||
| std::stringbuf buffer; | ||
| buffer.sputn(reinterpret_cast<const char*>(&hash_), sizeof(hash_)); | ||
| const auto& fragment_hash = fragment.hash(); | ||
| buffer.sputn(reinterpret_cast<const char*>(&fragment_hash), sizeof(fragment_hash)); | ||
| hash_ = HashUtil::xxHash64(buffer.str()); | ||
| } | ||
|
|
||
| uint64_t hash_{0}; | ||
| std::vector<std::unique_ptr<ScopeKeyFragmentBase>> fragments_; | ||
| }; | ||
|
|
||
| using ScopeKeyPtr = std::unique_ptr<ScopeKey>; | ||
|
|
||
| // String fragment. | ||
| class StringKeyFragment : public ScopeKeyFragmentBase { | ||
| public: | ||
| explicit StringKeyFragment(absl::string_view value) | ||
| : value_(value), hash_(HashUtil::xxHash64(value_)) {} | ||
|
|
||
| uint64_t hash() const override { return hash_; } | ||
|
|
||
| private: | ||
| const std::string value_; | ||
| const uint64_t hash_; | ||
| }; | ||
|
|
||
| /** | ||
| * The scoped routing configuration. | ||
| */ | ||
|
|
@@ -22,6 +93,13 @@ class ScopedConfig : public Envoy::Config::ConfigProvider::Config { | |
| * @return ConfigConstSharedPtr the router's Config matching the request headers. | ||
| */ | ||
| virtual ConfigConstSharedPtr getRouteConfig(const Http::HeaderMap& headers) const PURE; | ||
|
|
||
| /** | ||
| * Based on the incoming HTTP request headers, returns the hash value of its scope key. | ||
| * @param headers the request headers to match the scoped routing configuration against. | ||
| * @return unique_ptr of the scope key computed from header. | ||
| */ | ||
| virtual ScopeKeyPtr computeScopeKey(const Http::HeaderMap&) const { return {}; } | ||
| }; | ||
|
|
||
| using ScopedConfigConstSharedPtr = std::shared_ptr<const ScopedConfig>; | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.