func jitter(duration time.Duration, maxFactor float64) time.Duration {
	if maxFactor <= 0.0 {
		maxFactor = 1.0
	}
	wait := duration + time.Duration(rand.Float64()*maxFactor*float64(duration))
	return wait
}
Jitter returns a time.Duration between duration and duration + maxFactor *
duration.

This allows clients to avoid converging on periodic behavior. If maxFactor
is 0.0, a suggested default value will be chosen.
package retry
import (
	"math/rand"
	"net/http"
	"strings"
	"time"
	"github.com/Azure/go-autorest/autorest"
	"github.com/Azure/go-autorest/autorest/mocks"
	"k8s.io/klog/v2"
)
var _ autorest.Sender = mocks.NewSender()
type Backoff struct {
	Duration time.Duration
	Factor float64
	Jitter float64
	Steps int
	Cap time.Duration
	NonRetriableErrors []string
	RetriableHTTPStatusCodes []int
}
func NewBackoff(duration time.Duration, factor float64, jitter float64, steps int, cap time.Duration) *Backoff {
	return &Backoff{
		Duration: duration,
		Factor:   factor,
		Jitter:   jitter,
		Steps:    steps,
		Cap:      cap,
	}
}
func (b *Backoff) WithNonRetriableErrors(errs []string) *Backoff {
	newBackoff := *b
	newBackoff.NonRetriableErrors = errs
	return &newBackoff
}
func (b *Backoff) WithRetriableHTTPStatusCodes(httpStatusCodes []int) *Backoff {
	newBackoff := *b
	newBackoff.RetriableHTTPStatusCodes = httpStatusCodes
	return &newBackoff
}
func (b *Backoff) isNonRetriableError(rerr *Error) bool {
	if rerr == nil {
		return false
	}
	for _, err := range b.NonRetriableErrors {
		if strings.Contains(rerr.RawError.Error(), err) {
			return true
		}
	}
	return false
}
func (b *Backoff) Step() time.Duration {
	if b.Steps < 1 {
		if b.Jitter > 0 {
			return jitter(b.Duration, b.Jitter)
		}
		return b.Duration
	}
	b.Steps--
	duration := b.Duration
	if b.Factor != 0 {
		b.Duration = time.Duration(float64(b.Duration) * b.Factor)
		if b.Cap > 0 && b.Duration > b.Cap {
			b.Duration = b.Cap
			b.Steps = 0
		}
	}
	if b.Jitter > 0 {
		duration = jitter(duration, b.Jitter)
	}
	return duration
}