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

balancergroup: Add trigger point to gracefully switch a child #5251

Merged
merged 4 commits into from Mar 22, 2022

Conversation

zasweq
Copy link
Contributor

@zasweq zasweq commented Mar 18, 2022

This PR adds the functionality of being able to start the Graceful Switch process for a child of the balancer group. This is branched off #5245.

RELEASE NOTES: None

Comment on lines 354 to 362
sbc.builder = builder
// Even if you get an add and it persists builder but doesn't start
// balancer, this would leave graceful switch being nil, in which we are
// correctly overwriting with the recent builder here as well to use later.
// The graceful switch balancer's presence is an invariant of whether the
// balancer group is closed or not (if closed, nil, if started, present).
if sbc.balancer != nil {
sbc.gracefulSwitch()
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Why not make sbc.gracefulSwitch() take the builder as the input? Then it can update the field, and also do the nil check.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hmmm, is there a reason you prefer it this way? I switched it to this suggestion. I originally did it this way to keep it consistent with Add() (in regards to persisting the builder - maybe because object is being created there is why it makes sense there?).

Copy link
Contributor

Choose a reason for hiding this comment

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

The reason I prefer this is that, sbc.balancer should ideally dealt with as a private field of the subBalancerWrapper. It should only be read by the subBalancerWrapper methods, not outside.
And with the way it is, it's like sbc.gracefulSwitch only does half of the job.

The code is not updated. Did you not push? Or haven't changed it yet?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Weird, I swear I changed it but I must've lost it in a squash somewhere, sorry lol. Reimplemented, sending out now.

internal/balancergroup/balancergroup_test.go Show resolved Hide resolved
want = []balancer.SubConn{
sc,
}
if err := testutils.IsRoundRobin(want, subConnFromPicker(p2)); err != nil {
Copy link
Contributor

Choose a reason for hiding this comment

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

Is this checking that the picker only returns this one subconn? If so, don't use IsRoundRobin().

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Changed to just comparing deleted SubConn to wanted SubConn from Picker.


// READY will move this balancer into current, causing it to Update Client
// Conn with new Picker for this specific type of balancer, not round robin.
mb.cc.UpdateState(balancer.State{
Copy link
Contributor

Choose a reason for hiding this comment

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

Ideally, this should only happen after the SubConn state turns Ready.

And for this testing balancer, you can wrap pickfirst https://github.com/grpc/grpc-go/blob/master/pickfirst.go#L30
And override UpdateClientConnState to always delete the first address

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Switched to a wrapped PickFirst. I had to intercept an UpdateState() call with Idle as it calls that inline on the first successful UpdateState call for this to only trigger on SubConn being Ready. This also allowed me to verify that the Picker was not updated until Graceful Switch process was complete, as I now have a knob on that due to it being triggered by SubConnState change.

@menghanl menghanl assigned zasweq and unassigned menghanl Mar 21, 2022
Copy link
Contributor Author

@zasweq zasweq left a comment

Choose a reason for hiding this comment

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

Thanks for the comments :D!

Comment on lines 354 to 362
sbc.builder = builder
// Even if you get an add and it persists builder but doesn't start
// balancer, this would leave graceful switch being nil, in which we are
// correctly overwriting with the recent builder here as well to use later.
// The graceful switch balancer's presence is an invariant of whether the
// balancer group is closed or not (if closed, nil, if started, present).
if sbc.balancer != nil {
sbc.gracefulSwitch()
}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hmmm, is there a reason you prefer it this way? I switched it to this suggestion. I originally did it this way to keep it consistent with Add() (in regards to persisting the builder - maybe because object is being created there is why it makes sense there?).

internal/balancergroup/balancergroup_test.go Show resolved Hide resolved
want = []balancer.SubConn{
sc,
}
if err := testutils.IsRoundRobin(want, subConnFromPicker(p2)); err != nil {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Changed to just comparing deleted SubConn to wanted SubConn from Picker.


// READY will move this balancer into current, causing it to Update Client
// Conn with new Picker for this specific type of balancer, not round robin.
mb.cc.UpdateState(balancer.State{
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Switched to a wrapped PickFirst. I had to intercept an UpdateState() call with Idle as it calls that inline on the first successful UpdateState call for this to only trigger on SubConn being Ready. This also allowed me to verify that the Picker was not updated until Graceful Switch process was complete, as I now have a knob on that due to it being triggered by SubConnState change.

@zasweq zasweq force-pushed the balancer-group-add-graceful-switch branch from 8e7e033 to bfab353 Compare March 22, 2022 03:46
@@ -165,6 +165,20 @@ func (sbc *subBalancerWrapper) stopBalancer() {
sbc.balancer = nil
}

func (sbc *subBalancerWrapper) gracefulSwitch(builder balancer.Builder) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: move this above stopBalancer. I often treat methods close/stop as code boundaries.

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.

@zasweq zasweq merged commit 3a74cd5 into grpc:master Mar 22, 2022
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Sep 19, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants