diff --git a/retry/retry.go b/retry/retry.go index 38e6788a..d468ccae 100644 --- a/retry/retry.go +++ b/retry/retry.go @@ -124,6 +124,7 @@ func WithMaxAttempts(maxAttempts int) Option { // WithInitialBackoff sets initial backoff. // // If initial backoff option is not used, then default value of 50 milliseconds is used. +// If initial backoff is larger than max backoff, it takes precedence. func WithInitialBackoff(initialBackoff time.Duration) Option { return func(o *options) { o.initialBackoff = initialBackoff @@ -180,6 +181,8 @@ func Start(ctx context.Context, opts ...Option) Retrier { for _, option := range opts { option(&r.options) } + // If initial backoff is larger than max backoff, it takes precedence. + r.options.maxBackoff = max(r.options.maxBackoff, r.options.initialBackoff) r.Reset() return r } @@ -259,3 +262,10 @@ func (r retrier) retryIn() time.Duration { func (r retrier) CurrentAttempt() int { return r.currentAttempt } + +func max(a, b time.Duration) time.Duration { + if a > b { + return a + } + return b +} diff --git a/retry/retry_test.go b/retry/retry_test.go index cd76d803..eb584455 100644 --- a/retry/retry_test.go +++ b/retry/retry_test.go @@ -78,6 +78,25 @@ func TestRetrier_Next_WithMaxBackoff(t *testing.T) { } } +func TestRetrier_Next_WithInitialBackoffLargerThanMax(t *testing.T) { + const initialBackoff = time.Second * 5 + const maxBackoff = time.Second * 2 + + options := []Option{ + WithInitialBackoff(initialBackoff), + WithMaxBackoff(maxBackoff), + WithMultiplier(2), + WithMaxAttempts(11), + WithRandomizationFactor(0), + } + + r := Start(context.Background(), options...).(*retrier) + d := r.retryIn() + if d != initialBackoff { + t.Fatalf("expected initial backoff to be used: %s vs %s", d, initialBackoff) + } +} + func TestRetrier_Next_WithMaxAttempts(t *testing.T) { const maxAttempts = 2