-
Notifications
You must be signed in to change notification settings - Fork 4.6k
cleanup: replace dial with newclient #8602
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
base: master
Are you sure you want to change the base?
cleanup: replace dial with newclient #8602
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #8602 +/- ##
==========================================
+ Coverage 81.86% 81.87% +0.01%
==========================================
Files 415 416 +1
Lines 40694 40789 +95
==========================================
+ Hits 33316 33398 +82
- Misses 5993 6022 +29
+ Partials 1385 1369 -16 🚀 New features to boost your workflow:
|
"", | ||
"unix://a/b/c", | ||
"unix://authority", | ||
"unix-abstract://authority/a/b/c", | ||
"unix-abstract://authority", |
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 should not remove these test cases. Since NewClient
doesn't connect like Dial
, we need to do the following to get an error instead:
- Call cc.Connect()
- Wait for TRANSIENT_FAILURE state using AwaitState. If using this function causes a circular dependency, copy it over to this file, adding a comment that mentioning the reason for the duplication.
- If context times out before TF state, fail the 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.
I am using Idle because these malformed targets result in zero resolved addresses. The client never attempts a connection, so it stays IDLE and cannot reach TRANSIENT_FAILURE
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's an INFO log similar to the following from the unix resolver:
INFO clientconn.go:333 [core] [Channel #5] Channel failed to exit idle mode: invalid (non-empty) authority: authority (t=+1.01919ms)
Since this is the only indication that the connection attempt failed (no errors are returned), I think this should be logged as an ERROR. Presently, the method responsible for channelz trace event logging is logging everything at as an INFO log. We could have at accept the severity as an additional param to achieve this. Once this is an error log, we can assert that the error is logged similar to the following.
grpc-go/internal/transport/keepalive_test.go
Line 401 in 8389ddb
grpctest.ExpectError("Client received GoAway with error code ENHANCE_YOUR_CALM and debug data equal to ASCII \"too_many_pings\"") |
@dfawley do you think we should log the failure to exit idle mode in cc.Connect()
as an ERROR instead of INFO.
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.
Two options:
-
Change the unix name resolver not to error from
Build
when this happens. Instead, have it produce aResolverError
and otherwise do nothing. -
Handle
resolver.Build
errors so that all name resolvers that error duringBuild
will instead effectively produce aResolverError
. This fixes that class of problem in the same way for all name resolvers.
Either way, RPCs will fail with that error message text, and we shouldn't need anything besides INFO (or even V2?) logs.
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've raised a PR with the proposed change: #8643.
@vinothkumarr227 you can leave this test unchanged in this PR, I'll update the test at part of #8643.
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.
After investigating, I confirmed that RPCs already fail with the correct error message. The connection is attempted when the stream creation function calls exitIdle, as seen here:
Lines 180 to 186 in 2d92271
func newClientStream(ctx context.Context, desc *StreamDesc, cc *ClientConn, method string, opts ...CallOption) (_ ClientStream, err error) { | |
// Start tracking the RPC for idleness purposes. This is where a stream is | |
// created for both streaming and unary RPCs, and hence is a good place to | |
// track active RPC count. | |
if err := cc.idlenessMgr.OnCallBegin(); err != nil { | |
return nil, err | |
} |
Therefore, no changes are needed to propagate the error. While cc.Connect itself cannot return an error due to its signature, any resolver build failure is correctly surfaced to the user during the next RPC.
This test can be changes as follows to create a new stream and validate the error.
cc, err := NewClient(target, WithTransportCredentials(insecure.NewCredentials()))
if err != nil {
t.Fatalf("NewClient(%q) failed: %v", target, err)
}
defer cc.Close()
wantErrSubstr := "failed to exit idle mode"
if _, err := cc.NewStream(ctx, &StreamDesc{}, "/my.service.v1.MyService/UnaryCall"); err == nil {
t.Fatalf("NewStream() succeeded with target = %q, cc.parsedTarget = %+v, expected to fail", target, cc.parsedTarget)
} else if !strings.Contains(err.Error(), wantErrSubstr) {
t.Fatalf("NewStream() with target = %q returned unexpected error: got %v, want substring %q", target, err, wantErrSubstr)
}
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.
Thanks for the suggestion. I have modified the code changes accordingly
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.
In the team meeting, we discussed this and decided that we should keep the origin test that uses Dial
and add another test that uses NewClient
. Can you please add the original test back, keeping the updated one also?
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
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second) | ||
defer cancel() | ||
cc, err := NewClient(target, WithTransportCredentials(insecure.NewCredentials())) | ||
if err != nil { |
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 are changing the check condition here , is it intentional? If it is , the error message isn't correct. We are checking err!=nil
which means NewClient
failed and the error message says NewClient succeeded
which is not 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.
Done
} | ||
|
||
cc, err := Dial(test.target, WithTransportCredentials(insecure.NewCredentials()), WithContextDialer(dialer)) | ||
cc, err := NewClient(test.target, WithTransportCredentials(insecure.NewCredentials()), withDefaultScheme(defScheme), WithContextDialer(dialer)) |
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 don't think we should override the default scheme to passthrough
with new client because we want to check the behavior of parsed strings with defualt NewClient
function with custom dialer. And the behavior might be different , because dns
resolver also does its own parsing , so the results might be different. Correct me if I have understood incorrectly. But I think we should have a separate test for NewClient's
default parsed address behavior with custom dialer
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.
Thanks for your feedback, I used withDefaultScheme only in the specific tests where it’s needed, as suggested by Arjan. For checking the default NewClient behavior with a custom dialer, I’m not overriding the scheme. If you’d like a separate test specifically for NewClient's default behavior, let me know and I can add it.
clientconn_test.go
Outdated
if err != nil { | ||
t.Fatalf("Dial failed. Err: %v", err) | ||
} | ||
client.Connect() |
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.
Why did we add this here? We did not change from Dial
to NewClient
in the test and Dial will connect automatically?
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.
No need to change, I reverted it back.
"", | ||
"unix://a/b/c", | ||
"unix://authority", | ||
"unix-abstract://authority/a/b/c", | ||
"unix-abstract://authority", |
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's an INFO log similar to the following from the unix resolver:
INFO clientconn.go:333 [core] [Channel #5] Channel failed to exit idle mode: invalid (non-empty) authority: authority (t=+1.01919ms)
Since this is the only indication that the connection attempt failed (no errors are returned), I think this should be logged as an ERROR. Presently, the method responsible for channelz trace event logging is logging everything at as an INFO log. We could have at accept the severity as an additional param to achieve this. Once this is an error log, we can assert that the error is logged similar to the following.
grpc-go/internal/transport/keepalive_test.go
Line 401 in 8389ddb
grpctest.ExpectError("Client received GoAway with error code ENHANCE_YOUR_CALM and debug data equal to ASCII \"too_many_pings\"") |
@dfawley do you think we should log the failure to exit idle mode in cc.Connect()
as an ERROR instead of INFO.
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.
Mostly LGTM. Please address the pending comments and I'll add a second reviewer.
t.Fatalf("Dialing without a credential did not fail") | ||
// Ensure the NewClient fails without credentials | ||
if _, err := NewClient("fake"); err == nil { | ||
t.Fatalf("grpc.NewClient without a credential did not fail") |
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: Please use NewClient
instead of grpc.NewClient
in the log, i.e. omit the package name. Change this throughout.
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
"", | ||
"unix://a/b/c", | ||
"unix://authority", | ||
"unix-abstract://authority/a/b/c", | ||
"unix-abstract://authority", |
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.
In the team meeting, we discussed this and decided that we should keep the origin test that uses Dial
and add another test that uses NewClient
. Can you please add the original test back, keeping the updated one also?
noTSecStr := "no transport security set" | ||
if _, err := NewClient("fake", internal.DisableGlobalDialOptions.(func() DialOption)()); !strings.Contains(fmt.Sprint(err), noTSecStr) { | ||
t.Fatalf("grpc.NewClient received unexpected error: %v, want error containing \"%v\"", err, noTSecStr) | ||
t.Fatalf("NewClient received unexpected error: %q, want error containing %q", err, noTSecStr) |
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.
Please format errors with %v
, %q
should be used for strings.
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
noTSecStr := "no transport security set" | ||
if _, err := NewClient("dns:///fake"); !strings.Contains(fmt.Sprint(err), noTSecStr) { | ||
t.Fatalf("grpc.NewClient received unexpected error: %v, want error containing \"%v\"", err, noTSecStr) | ||
t.Fatalf("NewClient received unexpected error: %q, want error containing %q", err, noTSecStr) |
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.
Please format errors with %v
, %q
should be used for strings.
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
Fixes: #7049
RELEASE NOTES: None