retry: ensure that there's always at least one retry

Previously, if an operation failed after 15 minutes, then it would never
be retried. This means that large backend requests are more unreliable
than smaller ones.
This commit is contained in:
Michael Eischer 2024-04-29 21:16:24 +02:00
parent 72a4245890
commit 2b08353f29
1 changed files with 25 additions and 1 deletions

View File

@ -63,6 +63,30 @@ func retryNotifyErrorWithSuccess(operation backoff.Operation, b backoff.BackOff,
return err
}
func withRetryAtLeastOnce(delegate *backoff.ExponentialBackOff) *retryAtLeastOnce {
return &retryAtLeastOnce{delegate: delegate}
}
type retryAtLeastOnce struct {
delegate *backoff.ExponentialBackOff
numTries uint64
}
func (b *retryAtLeastOnce) NextBackOff() time.Duration {
delay := b.delegate.NextBackOff()
b.numTries++
if b.numTries == 1 && b.delegate.Stop == delay {
return b.delegate.InitialInterval
}
return delay
}
func (b *retryAtLeastOnce) Reset() {
b.numTries = 0
b.delegate.Reset()
}
var fastRetries = false
func (be *Backend) retry(ctx context.Context, msg string, f func() error) error {
@ -89,7 +113,7 @@ func (be *Backend) retry(ctx context.Context, msg string, f func() error) error
}
err := retryNotifyErrorWithSuccess(f,
backoff.WithContext(bo, ctx),
backoff.WithContext(withRetryAtLeastOnce(bo), ctx),
func(err error, d time.Duration) {
if be.Report != nil {
be.Report(msg, err, d)