Skip to content

Commit 65c7461

Browse files
tomo241rahul2393olavloite
authored
fix(spanner): retry INTERNAL retriable auth error (#12034)
* Make the INTERNAL error ""Authentication backend internal server error. Please retry" retryable. * Update spanner/retry.go Co-authored-by: Knut Olav Løite <[email protected]> * Set the initial and max backoff to 1 nanosecond instead of 1 millisecond, and the multiplier to 1.0 --------- Co-authored-by: rahul2393 <[email protected]> Co-authored-by: Knut Olav Løite <[email protected]>
1 parent dad4822 commit 65c7461

File tree

2 files changed

+36
-1
lines changed

2 files changed

+36
-1
lines changed

spanner/retry.go

+2-1
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,8 @@ func (r *spannerRetryer) Retry(err error) (time.Duration, bool) {
6565
!strings.Contains(err.Error(), "HTTP/2 error code: INTERNAL_ERROR") &&
6666
// See b/27794742.
6767
!strings.Contains(err.Error(), "Connection closed with unknown cause") &&
68-
!strings.Contains(err.Error(), "Received unexpected EOS on DATA frame from server") {
68+
!strings.Contains(err.Error(), "Received unexpected EOS on DATA frame from server") &&
69+
!strings.Contains(err.Error(), "Authentication backend internal server error. Please retry") {
6970
return 0, false
7071
}
7172

spanner/retry_test.go

+34
Original file line numberDiff line numberDiff line change
@@ -140,3 +140,37 @@ func TestRetryerRespectsServerDelayResourceExhausted(t *testing.T) {
140140
t.Fatalf("Retry delay mismatch:\ngot: %v\nwant: %v", maxSeenDelay, serverDelay)
141141
}
142142
}
143+
144+
func TestRunWithRetryOnInternalAuthError(t *testing.T) {
145+
ctx := context.Background()
146+
targetErr := status.Error(codes.Internal, "Authentication backend internal server error. Please retry")
147+
148+
callCount := 0
149+
// Mock function that fails with the target error first, then succeeds on the second attempt after retry.
150+
mockFunc := func(ctx context.Context) error {
151+
callCount++
152+
if callCount == 1 {
153+
return targetErr
154+
}
155+
return nil
156+
}
157+
158+
// Use a very short backoff for testing purposes to speed it up.
159+
originalBackoff := DefaultRetryBackoff
160+
DefaultRetryBackoff = gax.Backoff{
161+
Initial: 1 * time.Nanosecond,
162+
Max: 10 * time.Nanosecond,
163+
Multiplier: 1.0,
164+
}
165+
defer func() { DefaultRetryBackoff = originalBackoff }() // Restore original backoff
166+
167+
err := runWithRetryOnAbortedOrFailedInlineBeginOrSessionNotFound(ctx, mockFunc)
168+
169+
if err != nil {
170+
t.Errorf("Expected runWithRetry to succeed after retry, but got error: %v", err)
171+
}
172+
173+
if callCount != 2 {
174+
t.Errorf("Expected mockFunc to be called 2 times (1 initial + 1 retry), but got %d", callCount)
175+
}
176+
}

0 commit comments

Comments
 (0)