rds: extracting base classes as reusable generic routing DS implementation.#18846
rds: extracting base classes as reusable generic routing DS implementation.#18846htuch merged 16 commits intoenvoyproxy:mainfrom tkovacs-2:generic_rds
Conversation
Signed-off-by: Tamas Kovacs <tamas.2.kovacs@nokia-sbell.com>
|
@adisuissa do you want to take a first pas over this (see #17631 (comment))? |
|
/retest |
|
Retrying Azure Pipelines: |
|
/retest |
|
Retrying Azure Pipelines: |
adisuissa
left a comment
There was a problem hiding this comment.
Added a few comments.
This is a non-trivial change, and I'm still looking at the rest of the refactor here.
| public: | ||
| virtual ~RouteConfigProviderManager() = default; | ||
|
|
||
| virtual void eraseStaticProvider(RouteConfigProvider* provider) PURE; |
There was a problem hiding this comment.
Can the parameter be const?
When passing a pointer it typically means that it may be null. Is this the case here?
There was a problem hiding this comment.
Actually yes, any value is valid here. The pointer will be used just for lookup in a set.
It could be const but in the original implementation the set contained non-const pointers.
htuch
left a comment
There was a problem hiding this comment.
Out of curiosity, I'm wondering how much of what the RDS config distributor does is really routing specific? My understanding is we have something that can (1) create immutable shared data structures from proto (2) distribute/share this with worker threads and (2) act as a warming target. @adisuissa what are your thoughts on making that non-routing specific in a later PR if not this one?
Signed-off-by: Tamas Kovacs <tamas.2.kovacs@nokia-sbell.com>
Signed-off-by: Tamas Kovacs <tamas.2.kovacs@nokia-sbell.com>
|
I have moved the logic from the protocol specific manager completely to the |
|
Looks like the main branch has evolved recently and needs to be merged. /wait-any |
Signed-off-by: Tamas Kovacs <tamas.2.kovacs@nokia-sbell.com>
|
/retest |
|
Retrying Azure Pipelines: |
Signed-off-by: Tamas Kovacs <tamas.2.kovacs@nokia-sbell.com>
|
/retest |
|
Retrying Azure Pipelines: |
Signed-off-by: Tamas Kovacs <tamas.2.kovacs@nokia-sbell.com>
Probably fine, assuming there is a stat_prefix from each consumer supplied, it should be unique anyway.
Not sure? If it's not used, I'd drop it.
If the indirection isn't doing anything functional, I'd skip it. |
|
Thanks so much for the detailed commentary, very helpful. @adisuissa said he would take a look shortly. I've taken another pass over the implementation (not tests). LGTM, @envoyproxy/senior-maintainers this is a pretty major refactor of RDS (mostly mechanical). It doesn't have any runtime guarding, which would be hugely messy to implement I think. Any thoughts on whether we should be asking for runtime guarding here? I'm a little worried about the impact this PR might have |
I'm asking this because it is little cumbersome to downcast the provider pointer inside reference to |
|
I don't think so, that sounds broken if it is possible. |
Signed-off-by: Tamas Kovacs <tamas.2.kovacs@nokia-sbell.com>
|
/retest |
|
Retrying Azure Pipelines: |
Signed-off-by: Tamas Kovacs <tamas.2.kovacs@nokia-sbell.com>
Actually I have a feeling this change will be never merged, however I also understand concerns because the risks. |
|
@tkovacs-2 yep. Let me ping maintainers again. I rather simplify and merge the current PR as is if folks will accept the potential risk on control plane (and potential for rollback). Otherwise we should follow your strategy. |
|
I'm leaning towards merging without flag protection, since I think the only substantive change that might impact logic in a way that would not be obvious during canary and that poses risk here is around @tkovacs-2 do you agree with this assessment or are there are other parts of the PR you would consider risky? The other options is to consider increasing test coverage around the areas that seem risky. I do worry a bit about the dangers of having large amounts of duplicate code flag protected, we know from the unified gRPC mux experience this is really hard to maintain and is not a healthy state for the code base during the period of flag protection. |
There was a problem hiding this comment.
Thanks for working on this.
I left a few minor comments throughout the code (one thing to note: these comments are on the entire code that I've reviewed, and the underlying code could have been present before you made the refactor).
The main struggle I'm having when reviewing this PR, is that it is unclear what is new and what is moved/refactored. Ideally having a series of small PRs where the focus of each PR is on a single refactor, would be easier to verify and to convince ourselves that the changes won't break things.
All in all it this seems correct to me.
| */ | ||
| struct RdsStats { | ||
| ALL_RDS_STATS(GENERATE_COUNTER_STRUCT, GENERATE_GAUGE_STRUCT) | ||
| Rds::StaticRouteConfigProviderImpl base_; |
There was a problem hiding this comment.
Why is Rds::StaticRouteConfigProviderImpl a composed field (base_) instead of deriving the class from Rds::StaticRouteConfigProviderImpl?
There was a problem hiding this comment.
The Router::RouteConfigProvider adds couple methods to the Rds::RouteConfigProvider interface.
If I inherit from Rds::StaticRouteConfigProviderImpl those method are lost. However for static provider they are mostly not called, but called for dynamic providers. And static and dynamic providers should implement the same interface.
Inherit form both Rds::StaticRouteConfigProviderImpl and Router::RouteConfigProvider is also possible, but that leads to dimond inheritance and I thought the decorator pattern is better.
#18846 (comment) has some explanation of this. |
What simplification do you mean?
I wouldn't say risky but maybe these two parts worth bigger attention:
Also one question: |
Signed-off-by: Tamas Kovacs <tamas.2.kovacs@nokia-sbell.com>
adisuissa
left a comment
There was a problem hiding this comment.
Thanks for this refactor!
I've left a few comments/questions about the specific code segments you asked to validate.
IMHO using template method in this case (if I understand correctly) makes sense. If we use a utility function, then I'm assuming that it will have some kind of if/switch statement, which is less favorable (e.g., if new types (if any) will need to be added). Another option is to use templated methods, but then it would look very similar to the static_cast call. |
|
/wait |
Signed-off-by: Tamas Kovacs <tamas.2.kovacs@nokia-sbell.com>
For example there is this call from
I meant with the utility function the above call would look like this: |
htuch
left a comment
There was a problem hiding this comment.
LGTM modulo the one comment I left.
|
@tkovacs-2 thanks for your patient and working through the feedback. @adisuissa appreciate the review bandwidth. |
Commit Message:
Extracting base classes from the existing code as reusable generic routing DS implementation.
Additional Description:
base classes containing the generic part are extracted from the existing code.
(StaticRouteConfigProviderImpl, RdsRouteConfigProviderImpl, RouteConfigUpdateReceiverImpl)
and template method pattern (RdsRouteConfigSubscription).
which provides basic information about the otherwise opaque classes.
objects with the proper types.
This PR is split from #17631
Risk Level:
Medium
Testing:
Docs Changes:
Release Notes:
Platform Specific Features: