-
Notifications
You must be signed in to change notification settings - Fork 4.5k
ringhash: implement gRFC A76 #8159
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
Conversation
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #8159 +/- ##
==========================================
+ Coverage 81.91% 81.97% +0.06%
==========================================
Files 410 412 +2
Lines 40216 40498 +282
==========================================
+ Hits 32942 33198 +256
- Misses 5894 5912 +18
- Partials 1380 1388 +8
🚀 New features to boost your workflow:
|
- Add the ability to set the request hash header. This allows using ring hash without xDS. - Add the ability to specify the location of endpoints on the ring, and a default implementation based on EDS metadata that matches Envoy behavior. See https://github.com/grpc/proposal/blob/master/A76-ring-hash-improvements.md for details. Release Notes: - ringhash: implement gRFC A76.
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.
@@ -94,6 +98,27 @@ func (s) TestParseConfig(t *testing.T) { | |||
want: nil, | |||
wantErr: true, | |||
}, | |||
{ | |||
name: "request metadata key set", |
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.
there should be a test case for when there are multiple header values from the gRFC A76
If the header contains multiple values, then values are joined with a comma , character before hashing.
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.
The behavior joining headers with a coma is for header values. Using multiple headers is not supported. I added a picker test case for this, and took the opportunity to make the picker test a bit more robust by distributing endpoints on the ring, and removing unnecessary setting of the request hash in existing tests.
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.
Can we have a test for the case where the env var is set to false
and the JSON config contains a value for the request_hash_header
and we check that the parsed internal representation does not have the corresponding field set?
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.
The behavior joining headers with a coma is for header values. Using multiple headers is not supported. I added a picker test case for this
Ack. Thanks for adding this test.
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.
can we have a test for the case where the env var is set to false and the JSON config contains a value for the request_hash_header and we check that the parsed internal representation does not have the corresponding field set?
Added.
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.
Nit: Since we have multiple env vars in the context of ring_hash config parsing, could we please rename the field something more specific. Maybe requestHeaderEnvVar
?
Thanks for the review @danielzhaotongliu . I took your feedback into consideration. There is a failing test which I think may be flaky? (it's Test/End2End in the advancedtls module which seems unrelated). |
resolver/ringhash/attr.go
Outdated
// | ||
// Notice: This API is EXPERIMENTAL and may be changed or removed in a | ||
// later release. | ||
func SetEndpointHashKey(ep resolver.Endpoint, hashKey string) resolver.Endpoint { |
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.
nit: We can remove Endpoint
from the function name since the function argument type conveys this information.
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.
+1
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.
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.
Nit: s/hash key attribute of addr/hash key attribute of endpoint/
resolver/ringhash/attr.go
Outdated
// | ||
// Notice: This API is EXPERIMENTAL and may be changed or removed in a | ||
// later release. | ||
func SetEndpointHashKey(ep resolver.Endpoint, hashKey string) resolver.Endpoint { |
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.
+1
@@ -94,6 +98,27 @@ func (s) TestParseConfig(t *testing.T) { | |||
want: nil, | |||
wantErr: true, | |||
}, | |||
{ | |||
name: "request metadata key set", |
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.
The behavior joining headers with a coma is for header values. Using multiple headers is not supported. I added a picker test case for this
Ack. Thanks for adding this test.
I also fixed the configuration to use camelCase instead of snake_case: |
There is a race in a ringhash test caught by CI: https://github.com/grpc/grpc-go/actions/runs/14220675758/job/39847655816?pr=8159 |
Yep, that was just the err variable local to the test. Fixed in the latest commit. |
I also opened grpc/proposal#489 to clarify some of the behaviors I discovered during the implementation. It also answers the concern from @arjan-bal regarding duplicate hash keys. |
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.
LGTM!
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.
LGTM!
With gRFC A76 (grpc#8159), when requestHashHeader is specified from the service config it fails the validation since MD keys with uppercase letters are normalized to lowercase. We should normalize the parsed value before validation.
With gRFC A76 (grpc#8159), when requestHashHeader is specified from the service config it fails the validation since MD keys with uppercase letters are normalized to lowercase. We should normalize the parsed value before validation.
With gRFC A76 (grpc#8159), when requestHashHeader is specified from the service config it fails the validation since MD keys with uppercase letters are normalized to lowercase. We should normalize the parsed value before validation.
Fixes #8147, #7990.
Add the ability to set the request hash key, to extract the hash from a header. This allows using ring hash without xDS.
Add the ability to specify the location of endpoints on the ring, and a default implementation based on EDS metadata that matches Envoy behavior.
See https://github.com/grpc/proposal/blob/master/A76-ring-hash-improvements.md for details.
RELEASE NOTES: