Skip to content
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

Merged
merged 2 commits into from
Nov 29, 2018
Merged

Fixes #2943 - implements shared grpc connection per multiple EDS subscriptions. #5026

merged 2 commits into from
Nov 29, 2018

Conversation

dmitri-d
Copy link
Contributor

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.

Copy link
Member

@htuch htuch left a 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?

@dmitri-d
Copy link
Contributor Author

  • fixed broken tests


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,
Copy link
Member

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?

@repokitteh-read-only
Copy link

🙀 Error while processing event:

evaluation error
error: finished: error from server: {module load error GET https://api.github.com/repos/repokitteh/modules/contents/assign.star: 502 Server Error [] map[]}
🐱

Caused by: a #5026 (review) was submitted by @htuch.

see: more, trace.

@@ -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,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe use emplace?

@dmitri-d
Copy link
Contributor Author

@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,
Copy link
Member

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.

Copy link
Contributor Author

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?

Copy link
Member

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<
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just return directly?

Copy link
Contributor Author

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> {
Copy link
Member

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.

Copy link
Contributor Author

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...

Copy link
Member

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) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: s/Diffrent/Different/

Copy link
Contributor Author

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> {
Copy link
Member

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/mocks/local_info:local_info_mocks",
"//test/mocks/config:config_mocks",
"//test/mocks/runtime:runtime_mocks",
"//test/mocks/stats:stats_mocks",
Copy link
Member

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).

Copy link
Contributor Author

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) {
Copy link
Member

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?

Copy link
Contributor Author

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()));
Copy link
Member

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.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done.

@dmitri-d
Copy link
Contributor Author

  • rebased
  • renamed EdsGrpcSubscriptionImpl to GrpcManagedMuxSubscriptionImpl
  • Refactored GrpcSubscriptionImpl to become a wrapper around GrpcManagedMuxSubscptionImpl
  • Reduced visibility of EdsSubscriptionFactory::getOrCreateMux to protected

Still need to fix formatting.

@dmitri-d
Copy link
Contributor Author

  • fixed formatting of BUILD files

Copy link
Member

@htuch htuch left a 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));
Copy link
Member

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) {

Copy link
Member

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> {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.


namespace Envoy {
namespace Upstream {
class EdsSubscriptionFactory {
Copy link
Member

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
Copy link
Contributor Author

  • removed empty spaces as pointed above
  • added a reference to the original issue + a TODO note

@dmitri-d
Copy link
Contributor Author

  • signed-off and rebased

@htuch
Copy link
Member

htuch commented Nov 26, 2018

@dmitri-d still some format and tidy changes needed.

@dmitri-d
Copy link
Contributor Author

  • fixed formatting and clang_tidy issues

I'll squash and sign-off the commit once the latest changes will have been ok'd.

@htuch htuch changed the title [WIP] Fixes #2943 - implements shared grpc connection per multiple EDS subscriptions. Fixes #2943 - implements shared grpc connection per multiple EDS subscriptions. Nov 28, 2018
@dmitri-d
Copy link
Contributor Author

/retest

@repokitteh-read-only
Copy link

🔨 rebuilding ci/circleci: mac (failed build)

🐱

Caused by: a #5026 (comment) was created by @dmitri-d.

see: more, trace.

hello-ming and others added 2 commits November 28, 2018 18:32
Signed-off-by: hello-ming <hello.mingyu@gmail.com>
Signed-off-by: Dmitri Dolguikh <ddolguik@redhat.com>
@dmitri-d
Copy link
Contributor Author

  • rebased

@dmitri-d
Copy link
Contributor Author

/restest

@htuch htuch merged commit a085974 into envoyproxy:master Nov 29, 2018
@dmitri-d
Copy link
Contributor Author

Thanks for the reviews and the merge, @htuch.

adilhafeez added a commit to adilhafeez/envoy that referenced this pull request Dec 13, 2018
… multiple EDS subscriptions. (envoyproxy#5026)"

This reverts commit a085974.

Signed-off-by: Adil Hafeez <ahafeez@lyft.com>
mattklein123 pushed a commit that referenced this pull request Dec 14, 2018
…EDS subscriptions. (#5026)" (#5272)

This reverts commit a085974.

Signed-off-by: Adil Hafeez <ahafeez@lyft.com>
fredlas pushed a commit to fredlas/envoy that referenced this pull request Mar 5, 2019
…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>
fredlas pushed a commit to fredlas/envoy that referenced this pull request Mar 5, 2019
… 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>
@dmitri-d dmitri-d deleted the 2943-optimize-eds branch May 20, 2020 19:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants