Skip to content

Commit eb11ffd

Browse files
authored
retry: prevent per-RPC creds error from being transparently retried (#3677)
1 parent 9aa97f9 commit eb11ffd

File tree

3 files changed

+16
-19
lines changed

3 files changed

+16
-19
lines changed

balancer/grpclb/grpclb_test.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1351,9 +1351,9 @@ func (s) TestGRPCLBStatsUnaryFailedToSend(t *testing.T) {
13511351
cc.Invoke(context.Background(), failtosendURI, &testpb.Empty{}, nil)
13521352
}
13531353
}, &rpcStats{
1354-
numCallsStarted: int64(countRPC)*2 - 1,
1355-
numCallsFinished: int64(countRPC)*2 - 1,
1356-
numCallsFinishedWithClientFailedToSend: int64(countRPC-1) * 2,
1354+
numCallsStarted: int64(countRPC),
1355+
numCallsFinished: int64(countRPC),
1356+
numCallsFinishedWithClientFailedToSend: int64(countRPC) - 1,
13571357
numCallsFinishedKnownReceived: 1,
13581358
}); err != nil {
13591359
t.Fatal(err)
@@ -1444,9 +1444,9 @@ func (s) TestGRPCLBStatsStreamingFailedToSend(t *testing.T) {
14441444
cc.NewStream(context.Background(), &grpc.StreamDesc{}, failtosendURI)
14451445
}
14461446
}, &rpcStats{
1447-
numCallsStarted: int64(countRPC)*2 - 1,
1448-
numCallsFinished: int64(countRPC)*2 - 1,
1449-
numCallsFinishedWithClientFailedToSend: int64(countRPC-1) * 2,
1447+
numCallsStarted: int64(countRPC),
1448+
numCallsFinished: int64(countRPC),
1449+
numCallsFinishedWithClientFailedToSend: int64(countRPC) - 1,
14501450
numCallsFinishedKnownReceived: 1,
14511451
}); err != nil {
14521452
t.Fatal(err)

stream.go

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -459,26 +459,18 @@ func (cs *clientStream) commitAttempt() {
459459
// shouldRetry returns nil if the RPC should be retried; otherwise it returns
460460
// the error that should be returned by the operation.
461461
func (cs *clientStream) shouldRetry(err error) error {
462-
if cs.attempt.s == nil && !cs.callInfo.failFast {
463-
// In the event of any error from NewStream (attempt.s == nil), we
464-
// never attempted to write anything to the wire, so we can retry
465-
// indefinitely for non-fail-fast RPCs.
466-
return nil
467-
}
468462
if cs.finished || cs.committed {
469463
// RPC is finished or committed; cannot retry.
470464
return err
471465
}
472466
// Wait for the trailers.
473467
if cs.attempt.s != nil {
474468
<-cs.attempt.s.Done()
469+
if cs.firstAttempt && cs.attempt.s.Unprocessed() {
470+
// First attempt, stream unprocessed: transparently retry.
471+
return nil
472+
}
475473
}
476-
if cs.firstAttempt && (cs.attempt.s == nil || cs.attempt.s.Unprocessed()) {
477-
// First attempt, stream unprocessed: transparently retry.
478-
cs.firstAttempt = false
479-
return nil
480-
}
481-
cs.firstAttempt = false
482474
if cs.cc.dopts.disableRetry {
483475
return err
484476
}
@@ -564,6 +556,7 @@ func (cs *clientStream) retryLocked(lastErr error) error {
564556
cs.commitAttemptLocked()
565557
return err
566558
}
559+
cs.firstAttempt = false
567560
if err := cs.newAttemptLocked(nil, nil); err != nil {
568561
return err
569562
}

test/creds_test.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -189,11 +189,15 @@ func (s) TestGRPCMethodAccessibleToCredsViaContextRequestInfo(t *testing.T) {
189189
cc := te.clientConn(grpc.WithPerRPCCredentials(&methodTestCreds{}))
190190
tc := testpb.NewTestServiceClient(cc)
191191

192-
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
192+
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
193193
defer cancel()
194194
if _, err := tc.EmptyCall(ctx, &testpb.Empty{}); status.Convert(err).Message() != wantMethod {
195195
t.Fatalf("ss.client.EmptyCall(_, _) = _, %v; want _, _.Message()=%q", err, wantMethod)
196196
}
197+
198+
if _, err := tc.EmptyCall(ctx, &testpb.Empty{}, grpc.WaitForReady(true)); status.Convert(err).Message() != wantMethod {
199+
t.Fatalf("ss.client.EmptyCall(_, _) = _, %v; want _, _.Message()=%q", err, wantMethod)
200+
}
197201
}
198202

199203
const clientAlwaysFailCredErrorMsg = "clientAlwaysFailCred always fails"

0 commit comments

Comments
 (0)