-
Notifications
You must be signed in to change notification settings - Fork 4.7k
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
Fixes #2943 - implements shared grpc connection per multiple EDS subscriptions. #5026
Conversation
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.
The basic approach still looks good.. I'm curious why this is constrained to EDS so concretely? I think the same concerns also exist for RDS and possibly SDS. Would it make sense to templatize or something like that?
|
|
||
if (muxes_.find(mux_key) == muxes_.end()) { | ||
muxes_.insert({mux_key, | ||
std::unique_ptr<Config::GrpcMuxImpl>(new Config::GrpcMuxImpl(local_info, std::move(async_client), dispatcher, |
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.
Nit; std::make_unique is preferred in C++14. Do you need to std::move?
🙀 Error while processing event:
|
@@ -12,8 +12,8 @@ namespace Upstream { | |||
|
|||
if (muxes_.find(mux_key) == muxes_.end()) { | |||
muxes_.insert({mux_key, | |||
std::make_unique<Config::GrpcMuxImpl>(local_info, std::move(async_client), dispatcher, | |||
service_method, random, scope, rate_limit_settings)}); | |||
std::move(std::make_unique<Config::GrpcMuxImpl>(local_info, std::move(async_client), dispatcher, |
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.
Maybe use emplace
?
@htuch: looks like using emplace instead of insert did the trick. |
public: | ||
EdsSubscriptionFactory() : muxes_() {} | ||
|
||
Config::GrpcMux& getOrCreateMux(const LocalInfo::LocalInfo& local_info, Grpc::AsyncClientPtr async_client, |
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.
Should this be private? I don't think this is part of the interface.
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 not part of the interface, but I have tests for it. The only thing I can think of in order to keep tests (which I would like to do) is to subclass EdsSubscriptionFactory
in tests and add a proxy method for getOrCreateMux
. Would that work?
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, you can either use a testing peer pattern or provide a public getOrCreateMuxForTests
that makes clear this is only to be used in tests (and make the existing implementation private and the target).
return result; | ||
} | ||
|
||
auto to_return = Config::SubscriptionFactory::subscriptionFromConfigSource< |
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.
Just return directly?
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.
fixed.
namespace Envoy { | ||
namespace Config { | ||
|
||
class EdsGrpcSubscriptionImpl : public Config::Subscription<envoy::api::v2::ClusterLoadAssignment> { |
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'm still a bit confused what this is providing over GrpcSubscriptionImpl
? They seem to have the same implementation.
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.
Meant to ask you about this and then forgot. My understanding is that the instance of GrpcMux
in GrpcSubscriptionImpl
will be deallocated together with the main class. I need to pass a reference to GrpcMux
to EdsGrpcSubscriptionImpl
, as the mux instances are managed by EdsSubscriptionFactory
. Subscription classes are very much the same, but I wasn't sure how to reconcile mux ownership...
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.
Sure, I think we can refactor this a bit, have a base GrpcSubscriptionImpl
that takes a GrpcMux&
and then an OwnedGrpcSubscriptionImpl
subclass that creates and owns the GrpcMux
for those use cases.
ASSERT_TRUE(&first_mux == &second_mux); | ||
} | ||
|
||
TEST_F(EdsSubscriptionFactoryTest, ShouldReturnDiffrentMuxes) { |
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.
Nit: s/Diffrent/Different/
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.
fixed.
namespace Envoy { | ||
namespace Config { | ||
|
||
class EdsGrpcSubscriptionImpl : public Config::Subscription<envoy::api::v2::ClusterLoadAssignment> { |
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.
Sure, I think we can refactor this a bit, have a base GrpcSubscriptionImpl
that takes a GrpcMux&
and then an OwnedGrpcSubscriptionImpl
subclass that creates and owns the GrpcMux
for those use cases.
test/common/upstream/BUILD
Outdated
"//test/mocks/local_info:local_info_mocks", | ||
"//test/mocks/config:config_mocks", | ||
"//test/mocks/runtime:runtime_mocks", | ||
"//test/mocks/stats:stats_mocks", |
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.
This probably needs buildifier run on it (fix_format).
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.
done.
ASSERT_TRUE(&first_mux != &second_mux); | ||
} | ||
|
||
TEST_F(EdsSubscriptionFactoryTest, ShouldUseGetOrCreateMuxWhenApiConfigSourceIsUsed) { |
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.
Can you add a single line //
above each test explaining what it does in natural language?
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.
done.
random_, config.api_config_source(), stats_store_, rate_limit_settings_); | ||
|
||
Config::Subscription<envoy::api::v2::ClusterLoadAssignment>& eds_subscription = *subscription; | ||
ASSERT_TRUE(&expected_mux == &(dynamic_cast<Config::EdsGrpcSubscriptionImpl&>(eds_subscription).grpcMux())); |
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 you are after EXPECT
in all these final test statements, and specifically EXPECT_EQ
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.
done.
Still need to fix formatting. |
|
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.
Looks good!
Runtime::RandomGenerator& random, const ::envoy::api::v2::core::ApiConfigSource& config_source, | ||
Stats::Scope& scope, const Config::RateLimitSettings& rate_limit_settings) { | ||
|
||
const uint64_t mux_key = MessageUtil::hash(config_source.grpc_services(0)); |
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.
Nit: remove blank lines above/beyond, Google C++ style encourages dense packing of lines except where needed to logically divide up sections.
std::function<Config::Subscription<envoy::api::v2::ClusterLoadAssignment>*()> | ||
rest_legacy_constructor, | ||
const std::string& rest_method, const std::string& grpc_method) { | ||
|
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.
Nit: same here.
namespace Config { | ||
|
||
template <class ResourceType> | ||
class GrpcManagedMuxSubscriptionImpl : public Config::Subscription<ResourceType> { |
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.
We should make https://github.com/envoyproxy/envoy/blob/master/source/common/config/grpc_subscription_impl.h a subclass of this as discussed on Slack.
|
||
namespace Envoy { | ||
namespace Upstream { | ||
class EdsSubscriptionFactory { |
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.
A comment explaining what this does would be helpful, motivation, link back to original issue. Also a TODO explaining that it would make sense to generalize this for RDS in the future.
|
|
@dmitri-d still some format and tidy changes needed. |
I'll squash and sign-off the commit once the latest changes will have been ok'd. |
/retest |
🔨 rebuilding |
Signed-off-by: hello-ming <hello.mingyu@gmail.com>
Signed-off-by: Dmitri Dolguikh <ddolguik@redhat.com>
|
/restest |
Thanks for the reviews and the merge, @htuch. |
… multiple EDS subscriptions. (envoyproxy#5026)" This reverts commit a085974. Signed-off-by: Adil Hafeez <ahafeez@lyft.com>
…e EDS subscriptions. (envoyproxy#5026) Fixes envoyproxy#2943 by implementing shared grpc connection per multiple EDS subscriptions. Signed-off-by: Dmitri Dolguikh <ddolguik@redhat.com> Signed-off-by: Fred Douglas <fredlas@google.com>
… multiple EDS subscriptions. (envoyproxy#5026)" (envoyproxy#5272) This reverts commit a085974. Signed-off-by: Adil Hafeez <ahafeez@lyft.com> Signed-off-by: Fred Douglas <fredlas@google.com>
Was originally started in #4823.
Description: Fixes #2943 by implementing shared grpc connection per multiple EDS subscriptions.
Risk Level:
Testing:
Docs Changes:
Release Notes:
[Optional Fixes #Issue]
[Optional Deprecated:]
@htuch: I removed ClusterManager dependency on GrpcMuxFactory, as there was a circular dependency after some recent changed. The extacted code now lives in EdsSubscriptionFactory, and all changes I made are constrained within EDS.