From 6777b0746b87d7efb6c60455c00197d924599191 Mon Sep 17 00:00:00 2001 From: Shafayet Fahim Date: Mon, 23 Mar 2026 20:57:49 -0400 Subject: [PATCH] perf: skip retry sleep if context deadline is too short Introduce 100us buffer in WaitOrSkipRetry to fail-fast when the context will expire before the retry delay finishes. --- retry.go | 12 ++++++------ retryer_custom_test.go | 27 +++++++++++++++++++++++++++ 2 files changed, 33 insertions(+), 6 deletions(-) create mode 100644 retryer_custom_test.go diff --git a/retry.go b/retry.go index ccab507d..64659c41 100644 --- a/retry.go +++ b/retry.go @@ -72,14 +72,14 @@ func (r *retryer) WaitForRetry(ctx context.Context, duration time.Duration) { } } -func (r *retryer) WaitOrSkipRetry( - ctx context.Context, attempts int, cmd Completed, err error, -) bool { - if delay := r.RetryDelay(attempts, cmd, err); delay == 0 { +func (r *retryer) WaitOrSkipRetry(ctx context.Context, attempts int, cmd Completed, err error) bool { + delay := r.RetryDelay(attempts, cmd, err) + if delay == 0 { runtime.Gosched() return true - } else if delay > 0 { - if dl, ok := ctx.Deadline(); !ok || time.Until(dl) > delay { + } + if delay > 0 { + if dl, ok := ctx.Deadline(); !ok || time.Until(dl) > (delay+(100*time.Microsecond)) { r.WaitForRetry(ctx, delay) return true } diff --git a/retryer_custom_test.go b/retryer_custom_test.go new file mode 100644 index 00000000..a6be64bd --- /dev/null +++ b/retryer_custom_test.go @@ -0,0 +1,27 @@ +package rueidis + +import ( + "context" + "testing" + "time" +) + +func TestWaitOrSkipRetry_DeadlineBuffer(t *testing.T) { + r := newRetryer(func(attempts int, cmd Completed, err error) time.Duration { + return 10 * time.Millisecond // This will force a 10ms delay. + }) + + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Millisecond) + defer cancel() + + start := time.Now() // Returns false immediately b/c 5ms < 10ms + buffer inherently + retriable := r.WaitOrSkipRetry(ctx, 1, Completed{}, nil) + duration := time.Since(start) + + if retriable { + t.Errorf("Expected retriable to be false when deadline is shorter than delay") + } + if duration > 2*time.Millisecond { + t.Errorf("Expected function to return immediately, but it took %v", duration) + } +}