diff --git a/pkg/retry/retry.go b/pkg/retry/retry.go index 33469273..c3e0c70b 100644 --- a/pkg/retry/retry.go +++ b/pkg/retry/retry.go @@ -17,6 +17,8 @@ type IsRetryable func(error) bool type Settings struct { // Timeout lets WithBackoff give up once elapsed (if >0). Timeout time.Duration + // OnError is called if an error occurs. + OnError func(elapsed time.Duration, attempt uint64, err, lastErr error) } // WithBackoff retries the passed function if it fails and the error allows it to retry. @@ -30,13 +32,18 @@ func WithBackoff( defer cancelCtx() } - for attempt := 0; ; /* true */ attempt++ { + start := time.Now() + for attempt := uint64(0); ; /* true */ attempt++ { prevErr := err if err = retryableFunc(ctx); err == nil { return } + if settings.OnError != nil { + settings.OnError(time.Since(start), attempt, err, prevErr) + } + isRetryable := retryable(err) if prevErr != nil && (errors.Is(err, context.DeadlineExceeded) || errors.Is(err, context.Canceled)) { @@ -49,7 +56,7 @@ func WithBackoff( return } - sleep := b(uint64(attempt)) + sleep := b(attempt) select { case <-ctx.Done(): if err == nil {