type Backoff … // Step returns an amount of time to sleep determined by the original // Duration and Jitter. The backoff is mutated to update its Steps and // Duration. A nil Backoff always has a zero-duration step. func (b *Backoff) Step() time.Duration { … } // DelayFunc returns a function that will compute the next interval to // wait given the arguments in b. It does not mutate the original backoff // but the function is safe to use only from a single goroutine. func (b Backoff) DelayFunc() DelayFunc { … } // Timer returns a timer implementation appropriate to this backoff's parameters // for use with wait functions. func (b Backoff) Timer() Timer { … } // delay implements the core delay algorithm used in this package. func delay(steps int, duration, cap time.Duration, factor, jitter float64) (_ time.Duration, next time.Duration, nextSteps int) { … } // DelayWithReset returns a DelayFunc that will return the appropriate next interval to // wait. Every resetInterval the backoff parameters are reset to their initial state. // This method is safe to invoke from multiple goroutines, but all calls will advance // the backoff state when Factor is set. If Factor is zero, this method is the same as // invoking b.DelayFunc() since Steps has no impact without Factor. If resetInterval is // zero no backoff will be performed as the same calling DelayFunc with a zero factor // and steps. func (b Backoff) DelayWithReset(c clock.Clock, resetInterval time.Duration) DelayFunc { … } // Until loops until stop channel is closed, running f every period. // // Until is syntactic sugar on top of JitterUntil with zero jitter factor and // with sliding = true (which means the timer for period starts after the f // completes). func Until(f func(), period time.Duration, stopCh <-chan struct{ … } // UntilWithContext loops until context is done, running f every period. // // UntilWithContext is syntactic sugar on top of JitterUntilWithContext // with zero jitter factor and with sliding = true (which means the timer // for period starts after the f completes). func UntilWithContext(ctx context.Context, f func(context.Context), period time.Duration) { … } // NonSlidingUntil loops until stop channel is closed, running f every // period. // // NonSlidingUntil is syntactic sugar on top of JitterUntil with zero jitter // factor, with sliding = false (meaning the timer for period starts at the same // time as the function starts). func NonSlidingUntil(f func(), period time.Duration, stopCh <-chan struct{ … } // NonSlidingUntilWithContext loops until context is done, running f every // period. // // NonSlidingUntilWithContext is syntactic sugar on top of JitterUntilWithContext // with zero jitter factor, with sliding = false (meaning the timer for period // starts at the same time as the function starts). func NonSlidingUntilWithContext(ctx context.Context, f func(context.Context), period time.Duration) { … } // JitterUntil loops until stop channel is closed, running f every period. // // If jitterFactor is positive, the period is jittered before every run of f. // If jitterFactor is not positive, the period is unchanged and not jittered. // // If sliding is true, the period is computed after f runs. If it is false then // period includes the runtime for f. // // Close stopCh to stop. f may not be invoked if stop channel is already // closed. Pass NeverStop to if you don't want it stop. func JitterUntil(f func(), period time.Duration, jitterFactor float64, sliding bool, stopCh <-chan struct{ … } // BackoffUntil loops until stop channel is closed, run f every duration given by BackoffManager. // // If sliding is true, the period is computed after f runs. If it is false then // period includes the runtime for f. func BackoffUntil(f func(), backoff BackoffManager, sliding bool, stopCh <-chan struct{ … } // JitterUntilWithContext loops until context is done, running f every period. // // If jitterFactor is positive, the period is jittered before every run of f. // If jitterFactor is not positive, the period is unchanged and not jittered. // // If sliding is true, the period is computed after f runs. If it is false then // period includes the runtime for f. // // Cancel context to stop. f may not be invoked if context is already expired. func JitterUntilWithContext(ctx context.Context, f func(context.Context), period time.Duration, jitterFactor float64, sliding bool) { … } type backoffManager … // Step returns the expected next duration to wait. func (b *backoffManager) Step() time.Duration { … } // Backoff implements BackoffManager.Backoff, it returns a timer so caller can block on the timer // for exponential backoff. The returned timer must be drained before calling Backoff() the second // time. func (b *backoffManager) Backoff() clock.Timer { … } // Timer returns a new Timer instance that shares the clock and the reset behavior with all other // timers. func (b *backoffManager) Timer() Timer { … } type BackoffManager … type exponentialBackoffManagerImpl … // NewExponentialBackoffManager returns a manager for managing exponential backoff. Each backoff is jittered and // backoff will not exceed the given max. If the backoff is not called within resetDuration, the backoff is reset. // This backoff manager is used to reduce load during upstream unhealthiness. // // Deprecated: Will be removed when the legacy Poll methods are removed. Callers should construct a // Backoff struct, use DelayWithReset() to get a DelayFunc that periodically resets itself, and then // invoke Timer() when calling wait.BackoffUntil. // // Instead of: // // bm := wait.NewExponentialBackoffManager(init, max, reset, factor, jitter, clock) // ... // wait.BackoffUntil(..., bm.Backoff, ...) // // Use: // // delayFn := wait.Backoff{ // Duration: init, // Cap: max, // Steps: int(math.Ceil(float64(max) / float64(init))), // now a required argument // Factor: factor, // Jitter: jitter, // }.DelayWithReset(reset, clock) // wait.BackoffUntil(..., delayFn.Timer(), ...) func NewExponentialBackoffManager(initBackoff, maxBackoff, resetDuration time.Duration, backoffFactor, jitter float64, c clock.Clock) BackoffManager { … } func (b *exponentialBackoffManagerImpl) getNextBackoff() time.Duration { … } // Backoff implements BackoffManager.Backoff, it returns a timer so caller can block on the timer for exponential backoff. // The returned timer must be drained before calling Backoff() the second time func (b *exponentialBackoffManagerImpl) Backoff() clock.Timer { … } type jitteredBackoffManagerImpl … // NewJitteredBackoffManager returns a BackoffManager that backoffs with given duration plus given jitter. If the jitter // is negative, backoff will not be jittered. // // Deprecated: Will be removed when the legacy Poll methods are removed. Callers should construct a // Backoff struct and invoke Timer() when calling wait.BackoffUntil. // // Instead of: // // bm := wait.NewJitteredBackoffManager(duration, jitter, clock) // ... // wait.BackoffUntil(..., bm.Backoff, ...) // // Use: // // wait.BackoffUntil(..., wait.Backoff{Duration: duration, Jitter: jitter}.Timer(), ...) func NewJitteredBackoffManager(duration time.Duration, jitter float64, c clock.Clock) BackoffManager { … } func (j *jitteredBackoffManagerImpl) getNextBackoff() time.Duration { … } // Backoff implements BackoffManager.Backoff, it returns a timer so caller can block on the timer for jittered backoff. // The returned timer must be drained before calling Backoff() the second time func (j *jitteredBackoffManagerImpl) Backoff() clock.Timer { … } // ExponentialBackoff repeats a condition check with exponential backoff. // // It repeatedly checks the condition and then sleeps, using `backoff.Step()` // to determine the length of the sleep and adjust Duration and Steps. // Stops and returns as soon as: // 1. the condition check returns true or an error, // 2. `backoff.Steps` checks of the condition have been done, or // 3. a sleep truncated by the cap on duration has been completed. // In case (1) the returned error is what the condition function returned. // In all other cases, ErrWaitTimeout is returned. // // Since backoffs are often subject to cancellation, we recommend using // ExponentialBackoffWithContext and passing a context to the method. func ExponentialBackoff(backoff Backoff, condition ConditionFunc) error { … } // ExponentialBackoffWithContext repeats a condition check with exponential backoff. // It immediately returns an error if the condition returns an error, the context is cancelled // or hits the deadline, or if the maximum attempts defined in backoff is exceeded (ErrWaitTimeout). // If an error is returned by the condition the backoff stops immediately. The condition will // never be invoked more than backoff.Steps times. func ExponentialBackoffWithContext(ctx context.Context, backoff Backoff, condition ConditionWithContextFunc) error { … }