Skip to content

Commit 8c3abab

Browse files
sanki92kev-cao
authored andcommitted
util/retry: prioritize cancellations in retry loop
This commit teaches `util.Retry` to prioritize context cancellations and stoppers over retry attempts. This ensures more consistent behaviors and reduces test flakes. Fixes: #154764 Release note: None
1 parent e9a0b1c commit 8c3abab

File tree

3 files changed

+17
-33
lines changed

3 files changed

+17
-33
lines changed

pkg/util/retry/BUILD.bazel

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ go_test(
2525
],
2626
embed = [":retry"],
2727
deps = [
28-
"//pkg/testutils/skip",
2928
"//pkg/util/log",
3029
"//pkg/util/timeutil",
3130
"@com_github_cockroachdb_errors//:errors",

pkg/util/retry/retry.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,15 @@ func (r *Retry) Next() bool {
172172
return false
173173
}
174174

175+
// Check for cancellation first to prioritize over timer.
176+
select {
177+
case <-r.opts.Closer:
178+
return false
179+
case <-r.ctx.Done():
180+
return false
181+
default:
182+
}
183+
175184
backoff, actualWait, shouldAttempt := r.calcDurationScopedBackoff()
176185

177186
if !shouldAttempt && r.opts.PreemptivelyCancel {

pkg/util/retry/retry_test.go

Lines changed: 8 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ import (
1010
"testing"
1111
"time"
1212

13-
"github.com/cockroachdb/cockroach/pkg/testutils/skip"
1413
"github.com/cockroachdb/cockroach/pkg/util/timeutil"
1514
"github.com/cockroachdb/errors"
1615
"github.com/stretchr/testify/require"
@@ -402,11 +401,7 @@ func TestRetryWithMaxDuration(t *testing.T) {
402401
retryFunc func(attemptNum int) error
403402
preRetryFunc func()
404403
expectedTimeSpent time.Duration
405-
// For cases where the amount of time spent is not deterministic, we can set
406-
// an upper bound instead (e.g. for context or closer).
407-
maxExpectedTimeSpent time.Duration
408-
expectedErr bool
409-
skipUnderDuress bool
404+
expectedErr bool
410405
}
411406

412407
testCases := []testcase{
@@ -474,11 +469,8 @@ func TestRetryWithMaxDuration(t *testing.T) {
474469
preRetryFunc: func() {
475470
cancelCtxFunc()
476471
},
477-
maxExpectedTimeSpent: time.Millisecond * 20,
478-
expectedErr: true,
479-
// Under duress, closing a context will not necessarily stop the retry
480-
// loop immediately, so we skip this test under duress.
481-
skipUnderDuress: true,
472+
expectedTimeSpent: 0,
473+
expectedErr: true,
482474
},
483475
{
484476
name: "errors with opt.Closer that is closed",
@@ -494,20 +486,13 @@ func TestRetryWithMaxDuration(t *testing.T) {
494486
preRetryFunc: func() {
495487
close(closeCh)
496488
},
497-
maxExpectedTimeSpent: time.Millisecond * 20,
498-
expectedErr: true,
499-
// Under duress, closing a channel will not necessarily stop the retry
500-
// loop immediately, so we skip this test under duress.
501-
skipUnderDuress: true,
489+
expectedTimeSpent: 0,
490+
expectedErr: true,
502491
},
503492
}
504493

505494
for _, tc := range testCases {
506495
t.Run(tc.name, func(t *testing.T) {
507-
if tc.skipUnderDuress && skip.Duress() {
508-
skip.UnderDuress(t, "skipping test under duress: %s", tc.name)
509-
}
510-
511496
timeSource := timeutil.NewManualTime(time.Now())
512497
tc.opts.Clock = timeSource
513498
// Disable randomization for deterministic tests.
@@ -544,18 +529,9 @@ func TestRetryWithMaxDuration(t *testing.T) {
544529
require.NoError(t, err)
545530
}
546531

547-
if tc.expectedTimeSpent != 0 {
548-
require.Equal(
549-
t, tc.expectedTimeSpent, timeSource.Since(start), "expected time does not match actual spent time",
550-
)
551-
}
552-
553-
if tc.maxExpectedTimeSpent != 0 {
554-
require.LessOrEqual(
555-
t, timeSource.Since(start), tc.maxExpectedTimeSpent,
556-
"expected time spent to be less than or equal to max expected time spent",
557-
)
558-
}
532+
require.Equal(
533+
t, tc.expectedTimeSpent, timeSource.Since(start), "expected time does not match actual spent time",
534+
)
559535
})
560536
}
561537
}

0 commit comments

Comments
 (0)