func (p randomBackOff) String() string {
	return fmt.Sprintf("RandomBackOff(%dms-%dms)", p.minMS, p.maxMS)
}
String prints human readable information.
package retry
import (
	"fmt"
	"time"
	"github.com/bytedance/gopkg/lang/fastrand"
)
const maxFailureRetryTimes = 5
func NewFailurePolicy() *FailurePolicy {
	p := &FailurePolicy{
		StopPolicy: StopPolicy{
			MaxRetryTimes:    2,
			DisableChainStop: false,
			CBPolicy: CBPolicy{
				ErrorRate: defaultCBErrRate,
			},
		},
		BackOffPolicy: &BackOffPolicy{BackOffType: NoneBackOffType},
	}
	return p
}
func (p *FailurePolicy) WithMaxRetryTimes(retryTimes int) {
	if retryTimes < 0 || retryTimes > maxFailureRetryTimes {
		panic(fmt.Errorf("maxFailureRetryTimes is %d", maxFailureRetryTimes))
	}
	p.StopPolicy.MaxRetryTimes = retryTimes
}
func (p *FailurePolicy) WithMaxDurationMS(maxMS uint32) {
	p.StopPolicy.MaxDurationMS = maxMS
}
func (p *FailurePolicy) DisableChainRetryStop() {
	p.StopPolicy.DisableChainStop = true
}
func (p *FailurePolicy) WithDDLStop() {
	p.StopPolicy.DDLStop = true
}
func (p *FailurePolicy) WithFixedBackOff(fixMS int) {
	if err := checkFixedBackOff(fixMS); err != nil {
		panic(err)
	}
	p.BackOffPolicy = &BackOffPolicy{FixedBackOffType, make(map[BackOffCfgKey]float64, 1)}
	p.BackOffPolicy.CfgItems[FixMSBackOffCfgKey] = float64(fixMS)
}
func (p *FailurePolicy) WithRandomBackOff(minMS, maxMS int) {
	if err := checkRandomBackOff(minMS, maxMS); err != nil {
		panic(err)
	}
	p.BackOffPolicy = &BackOffPolicy{RandomBackOffType, make(map[BackOffCfgKey]float64, 2)}
	p.BackOffPolicy.CfgItems[MinMSBackOffCfgKey] = float64(minMS)
	p.BackOffPolicy.CfgItems[MaxMSBackOffCfgKey] = float64(maxMS)
}
func (p *FailurePolicy) WithRetryBreaker(errRate float64) {
	p.StopPolicy.CBPolicy.ErrorRate = errRate
	if err := checkCBErrorRate(&p.StopPolicy.CBPolicy); err != nil {
		panic(err)
	}
}
func (p *FailurePolicy) WithRetrySameNode() {
	p.RetrySameNode = true
}
func (p FailurePolicy) String() string {
	return fmt.Sprintf("{StopPolicy:%+v BackOffPolicy:%+v RetrySameNode:%+v}", p.StopPolicy, p.BackOffPolicy, p.RetrySameNode)
}
type BackOff interface {
	Wait(callTimes int)
}
var NoneBackOff = &noneBackOff{}
func newFixedBackOff(fixMS int) BackOff {
	return &fixedBackOff{
		fixMS: fixMS,
	}
}
func newRandomBackOff(minMS, maxMS int) BackOff {
	return &randomBackOff{
		minMS: minMS,
		maxMS: maxMS,
	}
}
type noneBackOff struct{}
func (p noneBackOff) String() string {
	return "NoneBackOff"
}
func (p *noneBackOff) Wait(callTimes int) {
}
type fixedBackOff struct {
	fixMS int
}
func (p *fixedBackOff) Wait(callTimes int) {
	time.Sleep(time.Duration(p.fixMS) * time.Millisecond)
}
func (p fixedBackOff) String() string {
	return fmt.Sprintf("FixedBackOff(%dms)", p.fixMS)
}
type randomBackOff struct {
	minMS int
	maxMS int
}
func (p *randomBackOff) randomDuration() time.Duration {
	return time.Duration(p.minMS+fastrand.Intn(p.maxMS-p.minMS)) * time.Millisecond
}
func (p *randomBackOff) Wait(callTimes int) {
	time.Sleep(p.randomDuration())
}