-
Notifications
You must be signed in to change notification settings - Fork 4.8k
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
discovery: refactor configuration ingestion. #11638
Conversation
Previously, the gRPC muxes required that decoding an opaque resource to obtain its name, then dispatch to the relevant subscription, which would again decode the opaque resource. This is pretty horrible efficiency wise, in particular when upgrading from v2 -> v3. In this patch, we introduce a DecodedResource wrapper and OpaqueResourceDecoder. The config ingestion module, e.g. GrpcMuxImpl, uses the OpaqueResourceDecoder to produce a typed DecodedResource, performing the decode once. This DecodedResource is then dispatched to the watching subscription. This provides > 20% speedup on the v2 -> v3 tax for eds_speed_test, decreasing from an overhead of 3.2x to 2.5x. It's also likely to unlock further optimizations as we now have a wrapper resource and simplifies subscription implementations, as they no longer need to deal with delta vs. SotW resource decoding in different ways. Risk level: Medium (configuration ingestion path changes). Testing: New unit tests for DecodedResourceImpl/OpaqueResourceDecoderImpl, updated existing unit tests to work with new interfaces. Partial solution to envoyproxy#11362 Signed-off-by: Harvey Tuch <htuch@google.com>
Signed-off-by: Harvey Tuch <htuch@google.com>
@pgenera FYI, this PR reduces v3 conversion overhead by 20-25%. |
Signed-off-by: Harvey Tuch <htuch@google.com>
/** | ||
* Invoked when raw config received from xDS wire. | ||
*/ | ||
class UntypedConfigUpdateCallbacks { |
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.
is there a reason this interface must still be maintained? Is it possible to make all callbacks use 'DecodedResource'
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.
It's used on the WatchMap
interface, prior to any resource decoding.
* @return SubscriptionPtr subscription object corresponding for config and type_url. | ||
*/ | ||
virtual SubscriptionPtr | ||
subscriptionFromConfigSource(const envoy::config::core::v3::ConfigSource& config, | ||
absl::string_view type_url, Stats::Scope& scope, | ||
SubscriptionCallbacks& callbacks) PURE; | ||
SubscriptionCallbacks& callbacks, | ||
OpaqueResourceDecoder& resource_decoder) PURE; |
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.
Are different decoders used for different subscriptions? If not, would it be better for the SubscriptionFactory implementation to be constructed with the decoder?
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.
Yeah, each resource decoder effectively capture the Any
conversion for the subscription type, so it has to be part of the args here.
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.
ok
SubscriptionCallbacks& callbacks) { | ||
auto watch = std::make_unique<GrpcMuxWatchImpl>(resources, callbacks, type_url, *this); | ||
SubscriptionCallbacks& callbacks, | ||
OpaqueResourceDecoder& resource_decoder) { |
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.
if the grpc_mux_impl uses the same resource_decoder to decode all resources, I think it makes sense to make it a member of the class
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.
As above, since this has the type-specific Any
conversion internally, we need to supply the resource decoder on each watch when muxing across types, i.e. ADS.
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.
got it
@wgallagher could you take another look, review feedback should be addressed, thanks. |
Signed-off-by: Harvey Tuch <htuch@google.com>
Also adding @mattklein123 as reviewer for maintainer approval. |
+1 lgtm |
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.
Nice, very cool. Some optional comments from my skim through.
/** | ||
* @return const Protobuf::Message& resource message reference. If hasResource() is false, this | ||
* will be the empty message. | ||
*/ | ||
virtual const Protobuf::Message& resource() const PURE; | ||
|
||
/** | ||
* @return bool does the xDS discovery response have a set resource payload? | ||
*/ | ||
virtual bool hasResource() const PURE; |
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.
From an interface perspective you might consider just returning an optional reference from resource()
and then I think you can do away with hasResource()
?
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.
Yeah, I tried that initially, but it's cleaner to do it this way, since some sites still want a resource (the empty resource) even if hasResource()
is false.
Signed-off-by: Harvey Tuch <htuch@google.com>
Previously, the gRPC muxes required decoding an opaque resource to
obtain its name, then dispatch to the relevant subscription, which would
again decode the opaque resource. This is pretty horrible efficiency
wise, in particular when upgrading from v2 -> v3.
In this patch, we introduce a DecodedResource wrapper and
OpaqueResourceDecoder. The config ingestion module, e.g. GrpcMuxImpl,
uses the OpaqueResourceDecoder to produce a typed DecodedResource,
performing the decode once. This DecodedResource is then dispatched
to the watching subscription.
This provides > 20% speedup on the v2 -> v3 tax for eds_speed_test,
decreasing from an overhead of 3.2x to 2.5x. It's also likely to unlock
further optimizations as we now have a wrapper resource and simplifies
subscription implementations, as they no longer need to deal with delta
vs. SotW resource decoding in different ways.
Risk level: Medium (configuration ingestion path changes).
Testing: New unit tests for
DecodedResourceImpl/OpaqueResourceDecoderImpl, updated existing unit
tests to work with new interfaces.
Partial solution to #11362
Signed-off-by: Harvey Tuch htuch@google.com