Skip to content

Refactor code for gracefully switching child LB policies.#22101

Merged
markdroth merged 1 commit intogrpc:masterfrom
markdroth:lb_graceful_switcher
Feb 28, 2020
Merged

Refactor code for gracefully switching child LB policies.#22101
markdroth merged 1 commit intogrpc:masterfrom
markdroth:lb_graceful_switcher

Conversation

@markdroth
Copy link
Copy Markdown
Member

@markdroth markdroth commented Feb 21, 2020

@muxi, this will probably be useful to you in the RLS policy you're implementing.

@markdroth markdroth added the release notes: no Indicates if PR should not be in release notes label Feb 21, 2020
@markdroth markdroth requested a review from muxi February 21, 2020 19:47
@markdroth markdroth force-pushed the lb_graceful_switcher branch from f105e86 to 07d42d8 Compare February 21, 2020 20:35
@markdroth
Copy link
Copy Markdown
Member Author

Sorry, had to do a force-push to bring in some changes. The last commit is still what's new here.

@markdroth
Copy link
Copy Markdown
Member Author

The main changes to look at are now in commits 07d42d8 and fb9cbcb.

@markdroth
Copy link
Copy Markdown
Member Author

I've merged in the changes that this depended on, so this PR now contains only its own changes. Feel free to review. Thanks!

@@ -0,0 +1,277 @@
//
// Copyright 2018 gRPC authors.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

2020

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

This is basically moving code from another file, and the code was originally written in 2018, so I'm going to keep that date.

@@ -0,0 +1,66 @@
//
// Copyright 2018 gRPC authors.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

2020

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

The code was originally written in 2018.

}
auto& lb_policy =
child_policy_ == nullptr ? child_policy_ : pending_child_policy_;
lb_policy = CreateChildPolicy(child_policy_name, *args.args);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Why would we want to dereference the pointer here and then take address again in this function? Can we pass const grpc_channel_args* instead?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

The handing of grpc_channel_args is inconsistent all across our codebase, unfortunately. It's one of our oldest types, long predating the conversion from C to C++, so most of our older interfaces take it as a pointer. However, the C++ convention is to pass read-only arguments as const references, so that's what we do in newer code.

At some point, I would like to find time to convert grpc_channel_args to C++ and fix all of our code to use a more idiomatic interface. But until then, these inconsistencies will have to remain.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Sounds reasonable. Is this convention a gRPC thing or it's in the cpp style? I searched through cppstype a bit but did not find any reference

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

It is in the style guide, but confusingly, it's buried in the middle of a section about output parameters, even though it's talking about input parameters:

https://google.github.io/styleguide/cppguide.html#Output_Parameters

"Input parameters are usually values or const references"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thanks for the pointer :)

parent_->child_policy_->interested_parties(),
parent_->interested_parties());
parent_->child_policy_ = std::move(parent_->pending_child_policy_);
} else if (!CalledByCurrentChild()) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This is very nit, but would it be a little bit less awkward if you change the negative condition to a positive condition? When I read this line I was like "why would we even care if it's not a pending and not a current child", then after 3 seconds it became "oh yea we do not care about this case indeed". Changing to a positive condition would make it flow easier I guess.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Can you give an example of what you mean by "a positive condition"? I'm not sure what you mean.

Note that I can't just change this to check that it is from the current child and then move line 67 inside of the body here, because we want line 67 to run even if the case of a pending child that has just gone READY and been swapped into being the current child.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Note that I can't just change this to check that it is from the current child

That was what I meant. And I see the point here; you are right.

parent_->pending_child_policy_ != nullptr
? parent_->pending_child_policy_.get()
: parent_->child_policy_.get();
if (child_ != latest_child_policy) return;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Could you explain why it's only the latest child policy that can trigger a reresolution? Maybe with a line of comment.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Done.

if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_glb_trace)) {
gpr_log(GPR_INFO, "[grpclb %p] Created new child policy %s (%p)", this,
name, lb_policy.get());
gpr_log(GPR_INFO, "[grpclb %p] Created new child policy (%p)", this,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Since we know it's a child policy handler that got created, maybe we can log "Created new child policy handler" to tell things apart better. But current state is also fine too. Ditto to the gpr_log a few lines above.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Done.

{"round_robin", Json::Object()},
}};
} else {
child_policy_config_json = it->second;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This could be a big copy. Consider use pointer for child_policy_config_json?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Done.

{"round_robin", Json::Object()},
}};
} else {
child_policy_json = it->second;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Ditto. Can we use pointer instead to avoid possible copy?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Done.

OrphanablePtr<LoadBalancingPolicy> CreateLbPolicyLocked(
const char* lb_policy_name, const grpc_channel_args& args,
TraceStringVector* trace_strings);
const grpc_channel_args& args);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Ditto. Use pointer instead of reference here?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

See my reply elsewhere. This is the normal C++ convention for passing a read-only parameter.

@markdroth
Copy link
Copy Markdown
Member Author

Known issues: #22181 #18504 #20198 #21993 #21364 #20677

@markdroth markdroth force-pushed the lb_graceful_switcher branch from a64b259 to 19e28b1 Compare February 28, 2020 16:18
@markdroth markdroth merged commit 5e98ad4 into grpc:master Feb 28, 2020
@markdroth markdroth deleted the lb_graceful_switcher branch February 28, 2020 20:34
gnossen pushed a commit to gnossen/grpc that referenced this pull request Mar 13, 2020
Refactor code for gracefully switching child LB policies.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

release notes: no Indicates if PR should not be in release notes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants