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
	}
	backoff *= 1 + bc.Jitter*(rand.Float64()*2-1)
	if backoff < 0 {
		return 0
	}
	return time.Duration(backoff)
}
/*
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.
package netutil
import (
	"math/rand"
	"time"
)
var DefaultBackoffConfig = BackoffConfig{
	MaxDelay:  120 * time.Second,
	BaseDelay: 1.0 * time.Second,
	Factor:    1.6,
	Jitter:    0.2,
}
type Backoff interface {
	Backoff(retries int) time.Duration
}
type BackoffConfig struct {
	MaxDelay time.Duration
	BaseDelay time.Duration
	Factor float64
	Jitter float64
}