RunF provides a convenient way to run a function f repeatedly until the context expires or f returns a non-nil error that is not ErrResetBackoff. When f returns ErrResetBackoff, RunF continues to run f, but resets its backoff state before doing so. backoff accepts an integer representing the number
(ctx context.Context, f func() error, backoff func(int) time.Duration)
| 84 | // backoff state before doing so. backoff accepts an integer representing the |
| 85 | // number of retries, and returns the amount of time to backoff. |
| 86 | func RunF(ctx context.Context, f func() error, backoff func(int) time.Duration) { |
| 87 | attempt := 0 |
| 88 | timer := time.NewTimer(0) |
| 89 | for ctx.Err() == nil { |
| 90 | select { |
| 91 | case <-timer.C: |
| 92 | case <-ctx.Done(): |
| 93 | timer.Stop() |
| 94 | return |
| 95 | } |
| 96 | |
| 97 | err := f() |
| 98 | if errors.Is(err, ErrResetBackoff) { |
| 99 | timer.Reset(0) |
| 100 | attempt = 0 |
| 101 | continue |
| 102 | } |
| 103 | if err != nil { |
| 104 | return |
| 105 | } |
| 106 | timer.Reset(backoff(attempt)) |
| 107 | attempt++ |
| 108 | } |
| 109 | } |