123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172 |
- package netutil
- import (
- "math/rand"
- "time"
- )
- // DefaultBackoffConfig uses values specified for backoff in common.
- var DefaultBackoffConfig = BackoffConfig{
- MaxDelay: 120 * time.Second,
- BaseDelay: 1.0 * time.Second,
- Factor: 1.6,
- Jitter: 0.2,
- }
- // Backoff defines the methodology for backing off after a call failure.
- type Backoff interface {
- // Backoff returns the amount of time to wait before the next retry given
- // the number of consecutive failures.
- Backoff(retries int) time.Duration
- }
- // BackoffConfig defines the parameters for the default backoff strategy.
- type BackoffConfig struct {
- // MaxDelay is the upper bound of backoff delay.
- MaxDelay time.Duration
- // baseDelay is the amount of time to wait before retrying after the first
- // failure.
- BaseDelay time.Duration
- // factor is applied to the backoff after each retry.
- Factor float64
- // jitter provides a range to randomize backoff delays.
- Jitter float64
- }
- /*
- // NOTE TODO avoid use unexcept config.
- func (bc *BackoffConfig) Fix() {
- md := bc.MaxDelay
- *bc = DefaultBackoffConfig
- if md > 0 {
- bc.MaxDelay = md
- }
- }
- */
- // Backoff returns the amount of time to wait before the next retry given
- // the number of consecutive failures.
- func (bc *BackoffConfig) Backoff(retries int) time.Duration {
- if retries == 0 {
- return bc.BaseDelay
- }
- backoff, max := float64(bc.BaseDelay), float64(bc.MaxDelay)
- for backoff < max && retries > 0 {
- backoff *= bc.Factor
- retries--
- }
- if backoff > max {
- backoff = max
- }
- // Randomize backoff delays so that if a cluster of requests start at
- // the same time, they won't operate in lockstep.
- backoff *= 1 + bc.Jitter*(rand.Float64()*2-1)
- if backoff < 0 {
- return 0
- }
- return time.Duration(backoff)
- }
|