// computeNextBackoff uses a truncated exponential backoff to compute the next
// backoff using the value of the exiting backoff. The returned duration is
// randomized in either direction by 1/20 to prevent tight loops from
// stabilizing.
355191
func computeNextBackoff(currBackoff time.Duration) time.Duration {
	// Double the current backoff, truncating if it exceeds our maximum.
	nextBackoff := 2 * currBackoff
	if nextBackoff > cfg.MaxBackoff {
		nextBackoff = cfg.MaxBackoff
	}

	// Using 1/10 of our duration as a margin, compute a random offset to
	// avoid the nodes entering connection cycles.
	margin := nextBackoff / 10

	var wiggle big.Int
	wiggle.SetUint64(uint64(margin))
	if _, err := rand.Int(rand.Reader, &wiggle); err != nil {
		// Randomizing is not mission critical, so we'll just return the
		// current backoff.
		return nextBackoff
	}

	// Otherwise add in our wiggle, but subtract out half of the margin so
	// that the backoff can tweaked by 1/20 in either direction.
	return nextBackoff + (time.Duration(wiggle.Uint64()) - margin/2)
}
105971
func (bc Config) 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)
}
117677
func WithBackOffStrategy(b backoff.BackOff) Option {
	return &option{
		name:  backoffStrategyKey,
		value: b,
	}
}
143431
func (i *impl) backoffPeriod() time.Duration {
	backoff, max := float64(i.opts.InitialBackoff), float64(i.opts.MaxBackoff)
	for j := 0; j < i.retries && backoff < max; j++ {
		backoff *= i.opts.BackoffFactor
	}
	if backoff > max {
		backoff = max
	}

	return time.Duration(backoff)
}
904237
func (b *baseBackoff) cancel() {
	if b.next != nil {
		close(b.next)
		b.next = nil
	}
	b.cancelFunc()
}
487566
func (b *Backoff) ComputeDelayForRequest(now time.Time) time.Duration {
	b.mutex.Lock()
	defer b.mutex.Unlock()

	// Apply exponential decay to the counters
	timeDeltaSeconds := now.Unix() - b.lastDecay
	if timeDeltaSeconds > b.decayIntervalSeconds {
		intervals := float64(timeDeltaSeconds) / float64(b.decayIntervalSeconds)
		decay := float32(math.Pow(b.decayFraction, intervals))
		b.countErrorsRequestLimit *= decay
		b.countRequests *= decay
		b.lastDecay = now.Unix()
	}

	// Count this request
	b.countRequests += 1.0

	// Compute the failure rate
	errorFraction := float32(0.0)
	if b.countRequests > 0.5 {
		// Avoid tiny residuals & rounding errors
		errorFraction = b.countErrorsRequestLimit / b.countRequests
	}

	// Ignore a low fraction of errors
	// This also allows them to time-out
	if errorFraction < 0.1 {
		return time.Duration(0)
	}

	// Delay by the max delay multiplied by the recent error rate
	// (i.e. we apply a linear delay function)
	// TODO: This is pretty arbitrary
	delay := time.Nanosecond * time.Duration(float32(b.maxDelay.Nanoseconds())*errorFraction)
	// Round down to the nearest second for sanity
	return time.Second * time.Duration(int(delay.Seconds()))
}
258791
func (bc Exponential) Backoff(retries int) time.Duration {
	if retries == 0 {
		return baseDelay
	}
	backoff, max := float64(baseDelay), float64(bc.MaxDelay)
	for backoff < max && retries > 0 {
		backoff *= 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 + jitter*(grpcrand.Float64()*2-1)
	if backoff < 0 {
		return 0
	}
	return time.Duration(backoff)
}
535798
func (b *Backoff) Copy() *Backoff {
	return &Backoff{
		Factor: b.Factor,
		Jitter: b.Jitter,
		Min:    b.Min,
		Max:    b.Max,
	}
}
141450
func backoff(min, max float64, iter int) time.Duration {
	backoff := math.Pow(2, float64(iter)/5) * min
	if backoff > max {
		backoff = max
	}
	return time.Duration(backoff) * time.Millisecond
}
930569
func (limiters *RateLimiters) BackOff(host string) {
	limiters.mu.Lock()
	defer limiters.mu.Unlock()

	var limiter *rate.Limiter
	if limiters.perHost == nil {
		limiters.perHost = map[string]*rate.Limiter{}
	}
	if rl, ok := limiters.perHost[host]; ok {
		limiter = rl
	} else {
		limiter = rate.NewLimiter(rate.Limit(limiters.RPS), limiters.Burst)
		limiters.perHost[host] = limiter
	}

	oldLimit := float64(limiter.Limit())
	newLimit := limiters.clip(oldLimit / backOffBy)
	if oldLimit != newLimit && limiters.Logger != nil {
		limiters.Logger.Log("info", "reducing rate limit", "host", host, "limit", strconv.FormatFloat(newLimit, 'f', 2, 64))
	}
	limiter.SetLimit(rate.Limit(newLimit))
}
1146697
func WithExponentialBackoff(initialBackoff time.Duration, webhookFn func() error) error {
	backoff := wait.Backoff{
		Duration: initialBackoff,
		Factor:   1.5,
		Jitter:   0.2,
		Steps:    5,
	}

	var err error
	wait.ExponentialBackoff(backoff, func() (bool, error) {
		err = webhookFn()
		// these errors indicate a transient error that should be retried.
		if net.IsConnectionReset(err) || apierrors.IsInternalError(err) || apierrors.IsTimeout(err) || apierrors.IsTooManyRequests(err) {
			return false, nil
		}
		// if the error sends the Retry-After header, we respect it as an explicit confirmation we should retry.
		if _, shouldRetry := apierrors.SuggestsClientDelay(err); shouldRetry {
			return false, nil
		}
		if err != nil {
			return false, err
		}
		return true, nil
	})
	return err
}
176710
func NewMockBackoff() *MockBackoff {
	return &MockBackoff{
		CloneFunc: &BackoffCloneFunc{
			defaultHook: func() backoff.Backoff {
				return nil
			},
		},
		NextIntervalFunc: &BackoffNextIntervalFunc{
			defaultHook: func() time.Duration {
				return 0
			},
		},
		ResetFunc: &BackoffResetFunc{
			defaultHook: func() {
				return
			},
		},
	}
}
397419
func (b *Backoff) duration(n uint64) (t time.Duration) {
	// Saturate pow
	pow := time.Duration(math.MaxInt64)
	if n < 63 {
		pow = 1 << n
	}

	t = b.interval * pow
	if t/pow != b.interval || t > b.maxDuration {
		t = b.maxDuration
	}

	return
}
427716
func (eb exponentialBackoff) wait() {
	time.Sleep(eb.currentDelay)
	eb.currentDelay = eb.b.Duration()
}
1069761
func (b *ExponentialBackoff) Next(ctx context.Context, err error) time.Duration {
	// Get Limited base delay.
	delay := b.Limited.Next(ctx, err)
	if delay == Stop {
		return Stop
	}

	// Bound our delay.
	if b.MaxDelay > 0 && b.MaxDelay < delay {
		delay = b.MaxDelay
	} else {
		// Calculate the next delay exponentially.
		multiplier := b.Multiplier
		if multiplier < 1 {
			multiplier = 2
		}
		b.Delay = time.Duration(float64(b.Delay) * multiplier)
	}
	return delay
}
64645
func (b *SimpleBackoff) Next(retry int) (time.Duration, bool) {
	b.Lock()
	defer b.Unlock()

	if retry >= len(b.ticks) {
		return 0, false
	}

	ms := b.ticks[retry]
	if b.jitter {
		ms = jitter(ms)
	}
	return time.Duration(ms) * time.Millisecond, true
}
548957
func (b *ExponentialBackoff) Next(retry int) (time.Duration, bool) {
	r := 1.0 + rand.Float64() // random number in [1..2]
	m := math.Min(r*b.t*math.Pow(b.f, float64(retry)), b.m)
	if m >= b.m {
		return 0, false
	}
	d := time.Duration(int64(m)) * time.Millisecond
	return d, true
}