-
Notifications
You must be signed in to change notification settings - Fork 4.4k
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
roundrobin: strip attributes from addresses #4024
Conversation
balancer/base/balancer.go
Outdated
aNoAttrs := a | ||
aNoAttrs.Attributes = nil | ||
addrsSet[aNoAttrs] = struct{}{} | ||
if _, ok := b.subConns[aNoAttrs]; !ok { |
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.
} else {
sc.UpdateAddresses(a)
}
In case the attributes change in a meaningful way (to the transport/grpc).
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.
Done.
10703ab
to
e0b3d58
Compare
balancer/base/balancer.go
Outdated
// changed. This is a noop if the current address is the same as the | ||
// old one (reflect.DeepEqual). |
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.
What does this mean? It shouldn't be a "true" nop. It should make it so these attributes are used if we ever need to reconnect.
Of course, we don't actually have any attributes that matter right now, besides the network type, which isn't something that it makes sense to change over time for the same address.
Maybe we should update the grpclb usage of Metadata
for the server name to go through attributes instead so we can test this?
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.
If reflect.DeepEqual returns true, sc.UpdateAddresses
would immediately return.
reflect.DeepEqual also compares the attributes, so this early return only happens when the new addresses is exactly the same as old.
This change has nothing to do with grpclb. And we will need changes in ClientConn to handle attributes.
That includes making the attributes hashable (or comparable?), and distinguish between the attributes that matter (for connection, e.g. creds), and those that only for balancers to use (e.g. hierarchy)
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.
reflect.DeepEqual also compares the attributes
Oh, I see what you are saying here. My mistake.
This change has nothing to do with grpclb.
No, but that's an example of a potential attribute that could affect the transport, besides network type. Changing it would allow us to test the change you just made. Actually, we could also implement a dummy handshaker to read the attributes and verify they were updated when a reconnect happens.
What I was thinking was:
- Push an address from the resolver with no attributes
- Connect
- Push the same address from the resolver but with new attributes
- Force disconnect/reconnect
- Verify new attributes are in use
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.
Added a test
balancer/base/balancer.go
Outdated
// changed. This is a noop if the current address is the same as the | ||
// old one (reflect.DeepEqual). | ||
// | ||
// TODO: delete this when this balancer reads attributes. |
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.
This is what Java does now. It's unclear if we should be trying to be more aggressive about forcing a reconnect to pick up the new attributes if we know they 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.
When we know how to hash attributes, and know which part of it matters for connections, it will be easier to decide a UpdateAddresses
is needed. And the SubConn would decide if it will reconnect to pick up the new attributes.
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.
will be easier to decide a UpdateAddresses is needed
Right -- my point is we will still need to call UpdateAddresses
in that case, so we won't be deleting this.
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 would still say we should delete the TODO. We will update the addresses when the attributes change in a meaningful way.
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.
Done
ea68d72
to
3d81524
Compare
8227351
to
469a7d0
Compare
if len(md1) != 0 { | ||
t.Fatalf("got md: %v, want empty metadata", md1) | ||
} | ||
case <-time.After(time.Microsecond * 100): |
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.
It's unclear which case is desired. Is this expected? If so we should Fatal
always above, right?
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.
Made the above always fatal.
…esses `attributes` is stripped from addresses before they are used as map keys. SubConns are still created with the original addresses (with attributes).
4268a4c
to
b67914f
Compare
Sad.... we implemented a custom resolver and picker to support load balancing by weight saved in |
@lemonlinger you may want to fork the base balancer at a version that was working for you. This is a problem with the way the base balancer is designed IMO. #3425 |
// Note that this doesn't handle the case where the attribute content is | ||
// different. So if users want to set different attributes to create | ||
// duplicate connections to the same backend, it doesn't work. This is | ||
// fine for now, because duplicate is done by setting Metadata today. |
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.
Hello @menghanl , we were using attributes to create duplicate connections to our backend because Metadata is deprecated. Is the current advice to use this deprecated API in order to create duplicate backend connections?
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.
Yes. Please use the deprecated Metadata field (it should be pretty stable, there's no plan to delete it). Sorry for the trouble.
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.
We're looking forward to when the attributes can be used for this again. Thanks for the reply!
attributes
is stripped from addresses before they are used as map keys.SubConns are still created with the original addresses (with attributes).