| 47 | } |
| 48 | |
| 49 | func (b BackoffHandler) GetMaxBackoffDuration(ctx context.Context) (time.Duration, bool) { |
| 50 | // Follows the same logic as Backoff, but without mutating the receiver. |
| 51 | // This select has to happen first to reflect the actual behaviour of the Backoff function. |
| 52 | select { |
| 53 | case <-ctx.Done(): |
| 54 | return time.Duration(0), false |
| 55 | default: |
| 56 | } |
| 57 | if !b.resetDeadline.IsZero() && b.Clock.Now().After(b.resetDeadline) { |
| 58 | // b.retries would be set to 0 at this point |
| 59 | return time.Second, true |
| 60 | } |
| 61 | if b.retries >= b.maxRetries && !b.retryForever { |
| 62 | return time.Duration(0), false |
| 63 | } |
| 64 | maxTimeToWait := b.GetBaseTime() * 1 << (b.retries + 1) |
| 65 | return maxTimeToWait, true |
| 66 | } |
| 67 | |
| 68 | // BackoffTimer returns a channel that sends the current time when the exponential backoff timeout expires. |
| 69 | // Returns nil if the maximum number of retries have been used. |