-
Notifications
You must be signed in to change notification settings - Fork 4.9k
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
server: Contain the Configuration::MainImpl directly in server objects. #5184
Conversation
…cases. Signed-off-by: Joshua Marantz <jmarantz@google.com>
Signed-off-by: Joshua Marantz <jmarantz@google.com>
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'd prefer to keep the std::unique_ptr<Configuration::Main>
pointer instead of referring to an implementation in the headers. That said, we could still simplify its initialization by replacing the reset
calls with make_unique
.
@venilnoronha as I said I'm not wedded to this but it has a PRO: less lines of code, and less conditional. What's the reason for your preferring it as is? We should probably leave a comment explaining the rationale. |
The reason is that the header is now adding a dependency on an implementation rather than just an abstraction. |
So your concern is mainly about compile-speed pulling in the extra header? That makes sense, though server.h is dependent on lots of other other impls so I'm not sure what's special about this one, and it would be good to converge on style preferences in https://github.com/envoyproxy/envoy/blob/master/STYLE.md. I do like the idea of making improvements to compile-speed (see #5182). I guess to have the object guaranteed present (to avoid conditionals) we'd have to have two variables in the class
and then init them like:
but applying this broadly would get boring. Maybe we should have some kind of |
It's both design and performance. I did see the references to other headers, and I think, we should address those in the future. Regarding your point on avoiding conditionals, I like the |
OK, I am back to wanting to push this PR forward as is, despite the fact that it adds a dependency. That's because the current state of the code is not clang-tidy-clean and this edit is the simplest way to make it clean. See #4997 (comment) for more details. |
That comment link doesn't take you to the right spot in #4997 -- here's the relevant part of the comment:
|
Here's a pattern that (I think) makes clang-tidy happy (will know in 40m) and also passes tests:
I think the solution offered in this PR is better though. |
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 understand your concerns about clang-tidy, but I think the change introduces bugs and it feels like change for change sake. I haven't read your previous complete conversation but is there some other way to make clang-tidy happy here without these changes?
/wait
@@ -106,8 +100,8 @@ void ValidationInstance::shutdown() { | |||
// do an abbreviated shutdown here since there's less to clean up -- for example, no workers to | |||
// exit. | |||
thread_local_.shutdownGlobalThreading(); | |||
if (config_ != nullptr && config_->clusterManager() != nullptr) { | |||
config_->clusterManager()->shutdown(); | |||
if (config_.clusterManager() != nullptr) { |
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 I already mentioned in the other PR, this is almost certainly not correct. The nullptr check was present previously because shutdown() can be called before there is a config. The cluster manager is created during initialize(). I don't think there is a guarantee that the cluster manager exists here. Same applies in the non-validation server I think (or for sure that one, maybe not this one).
The nullptr check you are looking for is not necessary in this PR because the member var is no longer a pointer. We are still checking that the cluster manager is non-null. Imo this is the cleanest option but in the comment above I gave a different one that sticks with an interface pointer rather than an impl value. |
Sorry, I clearly did not read this carefully enough. Yes, this is fine. OK I agree this is a good cleanup and it's worth it to have the impl inline. If we want to have tests that use the interface later we can revisit then. |
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.
LGTM with small comment. Also needs master merge.
/wait
config_.reset(main_config); | ||
main_config->initialize(bootstrap_, *this, *cluster_manager_factory_); | ||
// Now the configuration gets parsed. The configuration may start setting | ||
// thread local data per above. See MainImpl::initialize() for why ConfigImpl |
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 comment here is not quite accurate anymore, since we are not initializing a pointer which gets called through. We still need to call initialize() though after we have the factory setup. Can you fix up the comment inside MainImpl::initialize()?
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 the comment in configuraiton_impl.h at the declaration for initialize() is still accurate:
* Initialize the configuration. This happens here vs. the constructor because the initialization
* will call through the server into the config to get the cluster manager so the config object
* must be created already.
In this PR the language about 'pointer dance' here in this file has been changed.
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.
Pedantically, I think it's a little different. Previously, since we were using a pointer, we needed to create the object then call initialize so the pointer is valid. Now, we create the config when we create the server, but we don't initialize it until we have the various pieces (factory) that we need. Personally I would alter to make it more clear but up to you.
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 gave it another shot; ptal. I'm not sure if I've adequately captured your concern.
* MainImpl is created in two phases. In the first phase it is
* default-constructed without a configuration as part of the server. The
* server won't be fully populated yet. initialize() applies the
* configuration in the second phase, as it requires a fully populated server.
Signed-off-by: Joshua Marantz <jmarantz@google.com>
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.
master merge done.
config_.reset(main_config); | ||
main_config->initialize(bootstrap_, *this, *cluster_manager_factory_); | ||
// Now the configuration gets parsed. The configuration may start setting | ||
// thread local data per above. See MainImpl::initialize() for why ConfigImpl |
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 the comment in configuraiton_impl.h at the declaration for initialize() is still accurate:
* Initialize the configuration. This happens here vs. the constructor because the initialization
* will call through the server into the config to get the cluster manager so the config object
* must be created already.
In this PR the language about 'pointer dance' here in this file has been changed.
Signed-off-by: Joshua Marantz <jmarantz@google.com>
/retest |
🔨 rebuilding |
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.
LGTM
/wait
Signed-off-by: Joshua Marantz <jmarantz@google.com>
/retest |
🔨 rebuilding |
…s. (envoyproxy#5184) * Contain the Configuration::MainImpl directly in server objects, simplifying code and making it clang-tidy compliant. Signed-off-by: Joshua Marantz <jmarantz@google.com> Signed-off-by: Fred Douglas <fredlas@google.com>
Description: I bumped into this in #4997 due to clang-tidy and pulled it to this separate PR, as it's kind of outside the scope of #4997. I think this is the simplest option for making this code clang-tidy compliant.
Risk Level: low
Testing: //test/...
Docs Changes: n/a
Release Notes: n/a