upstream: Fallback policy per selector support#7087
upstream: Fallback policy per selector support#7087zuercher merged 20 commits intoenvoyproxy:masterfrom
Conversation
|
Please merge master to pick up #7090 |
29d9cde to
5d33bfe
Compare
|
Please add unit tests for the new functionality in the subset_lb_test.cc. |
|
@nezdolik seems like you need to fix DCO. Please follow this: https://github.com/envoyproxy/envoy/blob/master/CONTRIBUTING.md#fixing-dco To avoid missing DCO in a pushed commit in the future seems like enabling the commit hook ( |
Signed-off-by: Kateryna Nezdolii <nezdolik@spotify.com>
Signed-off-by: Kateryna Nezdolii <nezdolik@spotify.com>
Signed-off-by: Kateryna Nezdolii <nezdolik@spotify.com>
Signed-off-by: Kateryna Nezdolii <nezdolik@spotify.com>
|
Please add user documentation for the new feature here https://github.com/envoyproxy/envoy/blob/master/docs/root/intro/arch_overview/load_balancing/subsets.rst |
| } | ||
|
|
||
| void SubsetLoadBalancer::initSubsetSelectorMap() { | ||
| selectors_ = std::make_shared<SubsetSelectorMap>(); |
There was a problem hiding this comment.
Since selectors_ is always initialized, I suggest moving its initialization to the constructor initializer list or better yet initialize it right in the header at the point of definition.
There was a problem hiding this comment.
@yanavlasov cannot init selectors_ in the header, as it depends on field subset_selectors_ being initialised in constructor. Moved out this initialisation into separate method, as constructor body is already big and it could be hard to read. What do you think?
There was a problem hiding this comment.
I was suggesting to move just the first line where the pointer is initialized to point to an empty SubsetSelectorMap object to the header. However the way you have is fine as well.
| typedef std::unordered_map<HashedValue, LbSubsetEntryPtr> ValueSubsetMap; | ||
| typedef std::unordered_map<std::string, ValueSubsetMap> LbSubsetMap; | ||
|
|
||
| struct SubsetSelectorMap { |
There was a problem hiding this comment.
I think it is fine as it is. However you could likely simplify this. The subset fallback policy is fully identified by the set of selector keys for this subset. You can concatenate the sorted selector keys into one string and use it as a key for finding the fallback policy. In this way you do not need to build a trie and can just use std::unordered_set<std::string, envoy::api::v2::Cluster::LbSubsetConfig::LbSubsetSelectorFallbackPolicy>
There was a problem hiding this comment.
@yanavlasov agree that that way code would be simplified. Was thinking about tradeoff though, if to switch to plain map, on each lookupHosts call LB will have to perform concatenation of keys from match criteria to look it up in map. While first approach brings code complexity but is kind of precomputing things on LB object creation so that when lookupHosts called we just iterate over each match criteria key and look it up recursively in a trie. If it's not a big deal of match criteria keys concatenation (from memory usage perspective), then having plain map seems more beneficial.
Signed-off-by: Kateryna Nezdolii <nezdolik@spotify.com>
Signed-off-by: Kateryna Nezdolii <nezdolik@spotify.com>
|
@yanavlasov addressed some of review comments (added testing for compound selector, switched to struct for |
Signed-off-by: Kateryna Nezdolii <nezdolik@spotify.com>
Signed-off-by: Kateryna Nezdolii <nezdolik@spotify.com>
|
/retest |
|
🔨 rebuilding |
|
@nezdolik should panic mode also be configurable per selector? |
zuercher
left a comment
There was a problem hiding this comment.
Thanks! I had a question about how the map of subset selectors/fallback policies is constructed, but otherwise I think it looks pretty good.
| const auto& selector_keys = subset_selector->selector_keys_; | ||
| uint32_t pos = 0; | ||
| selectors = selectors_; | ||
| for (const auto& key : selector_keys) { |
There was a problem hiding this comment.
What do you think about skipping this loop if subset_selector->fallback_policy_ is undefined? As it stands, the default behavior will be to build up this data structure with all the subsets even if no subset has a custom fallback policy configured. If you skip adding the subsets with no custom fallback, then SubsetSelectorMap.fallback_policy_ doesn't need to be optional and you can get rid of that complicated ternary below.
There was a problem hiding this comment.
agree, thanks for pointing out
Signed-off-by: Kateryna Nezdolii <nezdolik@spotify.com>
Signed-off-by: Kateryna Nezdolii <nezdolik@spotify.com>
|
@rgs1 possibly yes, with this change in case there is override per selector and no hosts are found, |
Signed-off-by: Kateryna Nezdolii <nezdolik@spotify.com>
| HostPredicate predicate = [](const Host&) -> bool { return true; }; | ||
| selector_fallback_subset_any_ = std::make_unique<LbSubsetEntry>(); | ||
| selector_fallback_subset_any_->priority_subset_.reset( | ||
| new PrioritySubsetImpl(*this, predicate, locality_weight_aware_, scale_locality_weight_)); |
There was a problem hiding this comment.
nit: use make_shared() for consistency?
| default_subset_metadata_, std::placeholders::_1); | ||
| selector_fallback_subset_default_ = std::make_unique<LbSubsetEntry>(); | ||
| selector_fallback_subset_default_->priority_subset_.reset( | ||
| new PrioritySubsetImpl(*this, predicate, locality_weight_aware_, scale_locality_weight_)); |
While reading envoyproxy#7087, I noticed two things about subset_lb.{cc,h}: * a few shared_ptrs are assigned via make_unique, which works but is wasteful [extra allocation] * reset(new ...) is used, which is unsafe & not consistent with the rest of the file Signed-off-by: Raul Gutierrez Segales <rgs@pinterest.com>
While reading #7087, I noticed two things about subset_lb.{cc,h}: * a few shared_ptrs are assigned via make_unique, which works but is wasteful [extra allocation] * reset(new ...) is used, which is unsafe & not consistent with the rest of the file Signed-off-by: Raul Gutierrez Segales <rgs@pinterest.com>
Signed-off-by: Kateryna Nezdolii <nezdolik@spotify.com>
Signed-off-by: Kateryna Nezdolii <nezdolik@spotify.com>
|
@rgs1 switched back to |
Signed-off-by: Kateryna Nezdolii <nezdolik@spotify.com>
|
@zuercher merge conflict should be fixed now |
Signed-off-by: Kateryna Nezdolii nezdolik@spotify.com
Duplicate of #6124 but with completed development.
Description: This code change allows to redefine fallback policy per specific subset selector. Because of how existing
LbSubsetMaptrie data structure is organised (mapping subset key to values), is not possible to do lookups for fallback policy only based on subset keys (had to introduce additional trie that maps subset keys to keys and has fallback policy on leaf level). AdditionalLbSubsetSelectorFallbackPolicyenum required to correctly identify the case when fallback policy is not set for given selector (otherwise it would always default to NO_FALLBACK, breaking backwards compatibility, if field is not set we should use top level fallback policy instead).Risk Level: Medium
Testing: Done
Docs Changes: Updated related docs
Release Notes:
Fixes #5130