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

Re-resolve target when one connection becomes TransientFailure #1679

Merged
merged 3 commits into from
Nov 28, 2017

Conversation

menghanl
Copy link
Contributor

This allows ClientConn to get more up-to-date addresses from resolver.
ClientConn compares new addresses with the cached ones. So if resolver returns the same set of addresses, ClientConn will not notify balancer about it.

Also moved the initialization of resolver and balancer to avoid race. Balancer will only be started when ClientConn gets resolved addresses from balancer.

This allows ClientConn to get more up-to-date addresses from resolver.
ClientConn compares new addresses with the cached ones. So if resolver
returns the same set of addresses, ClientConn will not notify balancer
about it.

Also moved the initialization of resolver and balancer to avoid race.
Balancer will only be started when ClientConn gets resolved addresses
from balancer.
@menghanl menghanl added the Type: Feature New features or improvements in behavior label Nov 20, 2017
@dfawley dfawley self-assigned this Nov 21, 2017
return
}

if reflect.DeepEqual(cc.curAddresses, addrs) {
Copy link
Member

Choose a reason for hiding this comment

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

I have heard just importing the reflect package is a bad idea (in the form of performance or binary size or both?). We should look into that claim and remove it if so. Looks like we're already importing it, so LGTM for this PR.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We should try the cmp package.

clientconn.go Outdated
// First time handling resolved addresses. Build a balancer use either
// the builder specified by dial option, or pickfirst.
var builder balancer.Builder
if cc.dopts.balancerBuilder != nil {
Copy link
Member

Choose a reason for hiding this comment

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

Go style:

builder := cc.dopts.balancerBuilder
if builder == nil {
  builder = newPickfirstBuilder()
}

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
return
}
cc.mu.Unlock()
go r.resolveNow(o)
Copy link
Member

Choose a reason for hiding this comment

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

Can this result in multiple simultaneous outgoing calls to the resolver's ResolveNow method? Is that OK?

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 up to the resolver on how to deal with parallel ResolveNow(). In the dns resolver implementation, a new ResolveNow() is ignored if the previous one hasn't been processed.

From ClientConn's point, if multiple ResolveNow() result in multiple NewAddress() calls, only the last update will be kept. And we also ignore this update if it's the same as the cache we have.

Copy link
Member

Choose a reason for hiding this comment

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

Maybe we should add a comment to ResolveNow() to let users know that it could be called multiple times concurrently.

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.Lock()
r := cc.resolverWrapper
if r == nil {
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.

cc.mu.Lock()
r := cc.resolverWrapper
cc.mu.Unlock()
if r == nil {
  return
}
go r.resolveNow(o)

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

@dfawley dfawley assigned menghanl and unassigned dfawley Nov 21, 2017
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. All done. PTAL.

return
}

if reflect.DeepEqual(cc.curAddresses, addrs) {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

We should try the cmp package.

clientconn.go Outdated
// First time handling resolved addresses. Build a balancer use either
// the builder specified by dial option, or pickfirst.
var builder balancer.Builder
if cc.dopts.balancerBuilder != 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.

done

clientconn.go Outdated
cc.mu.Lock()
r := cc.resolverWrapper
if r == nil {
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
return
}
cc.mu.Unlock()
go r.resolveNow(o)
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 up to the resolver on how to deal with parallel ResolveNow(). In the dns resolver implementation, a new ResolveNow() is ignored if the previous one hasn't been processed.

From ClientConn's point, if multiple ResolveNow() result in multiple NewAddress() calls, only the last update will be kept. And we also ignore this update if it's the same as the cache we have.

@menghanl menghanl assigned dfawley and unassigned menghanl Nov 21, 2017
@menghanl menghanl merged commit 1e1a47f into grpc:master Nov 28, 2017
@menghanl menghanl deleted the balancer_resolve_now branch November 28, 2017 21:16
@dfawley dfawley added this to the 1.9 Release milestone Jan 2, 2018
@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.
Labels
Type: Feature New features or improvements in behavior
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants