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

Register and use default balancers and resolvers #1551

Merged
merged 11 commits into from Oct 19, 2017

Conversation

menghanl
Copy link
Contributor

@menghanl menghanl commented Oct 2, 2017

The default balancer will be pickfirst if no balancer is specified.
And roundrobin is registered by default.

When switching balancer, the old balancer will be closed first, and a new balancer will start.
There's a gap between, where we will do optimization later.

Also removed two tests:

  • TestDialWithBlockErrorOnBadCertificates
  • TestDialWithBlockErrorOnNonTemporaryErrorDialer

$switch-balancer-1$

@menghanl menghanl changed the title Bar default b a r Register and use default balancers and resolvers Oct 2, 2017
@menghanl menghanl force-pushed the bar_default_b_a_r branch 6 times, most recently from 15c0d49 to bd21314 Compare October 3, 2017 18:44
@menghanl menghanl requested a review from dfawley October 3, 2017 20:07
@dfawley dfawley self-assigned this Oct 4, 2017
@@ -99,7 +100,11 @@ func TestOneBackend(t *testing.T) {
}
defer test.cleanup()

cc, err := grpc.Dial(r.Scheme()+":///test.server", grpc.WithInsecure(), grpc.WithBalancerBuilder(newBuilder()))
rr := balancer.Get("roundrobin")
Copy link
Member

Choose a reason for hiding this comment

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

package balancer

const RoundRobin = "roundrobin"
// or
var RoundRobinBuilder = ....

?

If not, I think a const in this test would be better than repeatedly using the same string.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added a const (a var actually) to roundrobin_test.

In theory, a user can re-register a roundrobin and Get will return the new one. So a exported variable in balancer package won't work.

reply string
err error
)
// The second RPC should succeed with the first server.
Copy link
Member

Choose a reason for hiding this comment

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

I don't understand this comment... Why doesn't the first RPC succeed with the first server? Why try 1000 times if the second one should succeed?

Should we do several attempts that all return the same server? I.e. do calls until you get the one you want, then do ~3 more and make sure they all match the same one? (So we're sure we aren't round-robining.)

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

for _, s := range servers {
var up bool
for i := 0; i < 1000; i++ {
if err = Invoke(context.Background(), "/foo/bar", &req, &reply, cc); err != nil && ErrorDesc(err) == s.port {
Copy link
Member

Choose a reason for hiding this comment

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

So, this does 1k RPCs until it eventually sees the server it's looking for, then it repeats through each server.. Why do 1k attempts? Maybe the second run-through should only do a single attempt for each, since we know we have a connection to every server by then?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is not the real check. This is to make sure each server will be picked (all the subConns are connected).
The following loop does the real roundrobin check.

Copy link
Member

Choose a reason for hiding this comment

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

LGTM.

clientconn.go Outdated
cc.mu.Unlock()
return
}
defer cc.mu.Unlock()
Copy link
Member

Choose a reason for hiding this comment

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

If you move this above 626, then you don't need to do it inside the if

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.

clientconn.go Outdated
grpclog.Infof("ClientConn switching balancer to %q", name)

if cc.customBalancer {
grpclog.Infoln("failed to switch balancer because custom balancer was set")
Copy link
Member

Choose a reason for hiding this comment

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

Suggestion: I'd like to avoid "failed" here. Maybe something like "ignoring service config balancer configuration: WithBalancer DialOption used instead"

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

clientconn.go Outdated
cc.mu.Unlock()
return
}
defer cc.mu.Unlock()
Copy link
Member

Choose a reason for hiding this comment

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

Move this defer to the end and make it not a defer? Or move it to the top and remove the direct call on 659?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

No defer!

Copy link
Member

Choose a reason for hiding this comment

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

FWIW, defers are fine (and help with readability) as long as they're not on critical paths / high-frequency operations.

Copy link
Contributor Author

@menghanl menghanl 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 review. PTAL.

@@ -99,7 +100,11 @@ func TestOneBackend(t *testing.T) {
}
defer test.cleanup()

cc, err := grpc.Dial(r.Scheme()+":///test.server", grpc.WithInsecure(), grpc.WithBalancerBuilder(newBuilder()))
rr := balancer.Get("roundrobin")
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added a const (a var actually) to roundrobin_test.

In theory, a user can re-register a roundrobin and Get will return the new one. So a exported variable in balancer package won't work.

clientconn.go Outdated
cc.mu.Unlock()
return
}
defer cc.mu.Unlock()
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.

clientconn.go Outdated
grpclog.Infof("ClientConn switching balancer to %q", name)

if cc.customBalancer {
grpclog.Infoln("failed to switch balancer because custom balancer was set")
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

clientconn.go Outdated
cc.mu.Unlock()
return
}
defer cc.mu.Unlock()
Copy link
Contributor Author

Choose a reason for hiding this comment

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

No defer!

reply string
err error
)
// The second RPC should succeed with the first server.
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

for _, s := range servers {
var up bool
for i := 0; i < 1000; i++ {
if err = Invoke(context.Background(), "/foo/bar", &req, &reply, cc); err != nil && ErrorDesc(err) == s.port {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is not the real check. This is to make sure each server will be picked (all the subConns are connected).
The following loop does the real roundrobin check.

clientconn.go Outdated
cc.mu.Unlock()
return
}
defer cc.mu.Unlock()
Copy link
Member

Choose a reason for hiding this comment

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

FWIW, defers are fine (and help with readability) as long as they're not on critical paths / high-frequency operations.

for _, s := range servers {
var up bool
for i := 0; i < 1000; i++ {
if err = Invoke(context.Background(), "/foo/bar", &req, &reply, cc); err != nil && ErrorDesc(err) == s.port {
Copy link
Member

Choose a reason for hiding this comment

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

LGTM.

@thelinuxfoundation
Copy link

Thank you for your pull request. Before we can look at your contribution, we need to ensure all contributors are covered by a Contributor License Agreement.

After the following items are addressed, please respond with a new comment here, and the automated system will re-verify.

Regards,
The Linux Foundation CLA GitHub bot

@menghanl menghanl merged commit a353537 into grpc:master Oct 19, 2017
@menghanl menghanl deleted the bar_default_b_a_r branch October 19, 2017 18:32
menghanl added a commit to menghanl/grpc-go that referenced this pull request Oct 25, 2017
@menghanl menghanl added this to the 1.8 Release milestone Nov 7, 2017
@lock lock bot locked as resolved and limited conversation to collaborators Jan 18, 2019
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

3 participants