diff --git a/go.mod b/go.mod index c8567afdad..60b76dd842 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,7 @@ go 1.21 require ( github.com/aws/aws-sdk-go v1.35.17 - github.com/cenkalti/backoff/v4 v4.0.0 + github.com/cenkalti/backoff/v4 v4.2.1 github.com/cespare/xxhash/v2 v2.1.1 github.com/go-chi/chi/v5 v5.0.0 github.com/go-chi/render v1.0.0 diff --git a/go.sum b/go.sum index a935661ea6..5201467837 100644 --- a/go.sum +++ b/go.sum @@ -99,8 +99,8 @@ github.com/buengese/sgzip v0.1.1 h1:ry+T8l1mlmiWEsDrH/YHZnCVWD2S3im1KLsyO+8ZmTU= github.com/buengese/sgzip v0.1.1/go.mod h1:i5ZiXGF3fhV7gL1xaRRL1nDnmpNj0X061FQzOS8VMas= github.com/calebcase/tmpfile v1.0.2 h1:1AGuhKiUu4J6wxz6lxuF6ck3f8G2kaV6KSEny0RGCig= github.com/calebcase/tmpfile v1.0.2/go.mod h1:iErLeG/iqJr8LaQ/gYRv4GXdqssi3jg4iSzvrA06/lw= -github.com/cenkalti/backoff/v4 v4.0.0 h1:6VeaLF9aI+MAUQ95106HwWzYZgJJpZ4stumjj6RFYAU= -github.com/cenkalti/backoff/v4 v4.0.0/go.mod h1:eEew/i+1Q6OrCDZh3WiXYv3+nJwBASZ8Bog/87DQnVg= +github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM= +github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY= diff --git a/pkg/util/retry/retry.go b/pkg/util/retry/retry.go index b5b89185f3..2ca25e14f4 100644 --- a/pkg/util/retry/retry.go +++ b/pkg/util/retry/retry.go @@ -25,7 +25,7 @@ func WithNotify(ctx context.Context, op Operation, b Backoff, n Notify) error { // Permanent wraps the given err in a *backoff.PermanentError. // This error interrupts further retries and causes retrying mechanism. -func Permanent(err error) *backoff.PermanentError { +func Permanent(err error) error { return backoff.Permanent(err) } diff --git a/vendor/github.com/cenkalti/backoff/v4/.gitignore b/vendor/github.com/cenkalti/backoff/v4/.gitignore index 00268614f0..50d95c548b 100644 --- a/vendor/github.com/cenkalti/backoff/v4/.gitignore +++ b/vendor/github.com/cenkalti/backoff/v4/.gitignore @@ -20,3 +20,6 @@ _cgo_export.* _testmain.go *.exe + +# IDEs +.idea/ diff --git a/vendor/github.com/cenkalti/backoff/v4/.travis.yml b/vendor/github.com/cenkalti/backoff/v4/.travis.yml deleted file mode 100644 index 871150c467..0000000000 --- a/vendor/github.com/cenkalti/backoff/v4/.travis.yml +++ /dev/null @@ -1,10 +0,0 @@ -language: go -go: - - 1.12 - - 1.x - - tip -before_install: - - go get github.com/mattn/goveralls - - go get golang.org/x/tools/cmd/cover -script: - - $HOME/gopath/bin/goveralls -service=travis-ci diff --git a/vendor/github.com/cenkalti/backoff/v4/README.md b/vendor/github.com/cenkalti/backoff/v4/README.md index cabfc9c701..16abdfc084 100644 --- a/vendor/github.com/cenkalti/backoff/v4/README.md +++ b/vendor/github.com/cenkalti/backoff/v4/README.md @@ -11,8 +11,7 @@ The retries exponentially increase and stop increasing when a certain threshold Import path is `github.com/cenkalti/backoff/v4`. Please note the version part at the end. -godoc.org does not support modules yet, -so you can use https://godoc.org/gopkg.in/cenkalti/backoff.v4 to view the documentation. +Use https://pkg.go.dev/github.com/cenkalti/backoff/v4 to view the documentation. ## Contributing @@ -20,7 +19,7 @@ so you can use https://godoc.org/gopkg.in/cenkalti/backoff.v4 to view the docume * Please don't send a PR without opening an issue and discussing it first. * If proposed change is not a common use case, I will probably not accept it. -[godoc]: https://godoc.org/github.com/cenkalti/backoff +[godoc]: https://pkg.go.dev/github.com/cenkalti/backoff/v4 [godoc image]: https://godoc.org/github.com/cenkalti/backoff?status.png [travis]: https://travis-ci.org/cenkalti/backoff [travis image]: https://travis-ci.org/cenkalti/backoff.png?branch=master @@ -30,4 +29,4 @@ so you can use https://godoc.org/gopkg.in/cenkalti/backoff.v4 to view the docume [google-http-java-client]: https://github.com/google/google-http-java-client/blob/da1aa993e90285ec18579f1553339b00e19b3ab5/google-http-client/src/main/java/com/google/api/client/util/ExponentialBackOff.java [exponential backoff wiki]: http://en.wikipedia.org/wiki/Exponential_backoff -[advanced example]: https://godoc.org/github.com/cenkalti/backoff#example_ +[advanced example]: https://pkg.go.dev/github.com/cenkalti/backoff/v4?tab=doc#pkg-examples diff --git a/vendor/github.com/cenkalti/backoff/v4/context.go b/vendor/github.com/cenkalti/backoff/v4/context.go index fcff86c1b3..48482330eb 100644 --- a/vendor/github.com/cenkalti/backoff/v4/context.go +++ b/vendor/github.com/cenkalti/backoff/v4/context.go @@ -57,10 +57,6 @@ func (b *backOffContext) NextBackOff() time.Duration { case <-b.ctx.Done(): return Stop default: + return b.BackOff.NextBackOff() } - next := b.BackOff.NextBackOff() - if deadline, ok := b.ctx.Deadline(); ok && deadline.Sub(time.Now()) < next { // nolint: gosimple - return Stop - } - return next } diff --git a/vendor/github.com/cenkalti/backoff/v4/exponential.go b/vendor/github.com/cenkalti/backoff/v4/exponential.go index fae5b6c327..2c56c1e718 100644 --- a/vendor/github.com/cenkalti/backoff/v4/exponential.go +++ b/vendor/github.com/cenkalti/backoff/v4/exponential.go @@ -115,11 +115,13 @@ func (b *ExponentialBackOff) Reset() { // Randomized interval = RetryInterval * (1 ± RandomizationFactor) func (b *ExponentialBackOff) NextBackOff() time.Duration { // Make sure we have not gone over the maximum elapsed time. - if b.MaxElapsedTime != 0 && b.GetElapsedTime() > b.MaxElapsedTime { + elapsed := b.GetElapsedTime() + next := getRandomValueFromInterval(b.RandomizationFactor, rand.Float64(), b.currentInterval) + b.incrementCurrentInterval() + if b.MaxElapsedTime != 0 && elapsed+next > b.MaxElapsedTime { return b.Stop } - defer b.incrementCurrentInterval() - return getRandomValueFromInterval(b.RandomizationFactor, rand.Float64(), b.currentInterval) + return next } // GetElapsedTime returns the elapsed time since an ExponentialBackOff instance @@ -143,8 +145,11 @@ func (b *ExponentialBackOff) incrementCurrentInterval() { } // Returns a random value from the following interval: -// [randomizationFactor * currentInterval, randomizationFactor * currentInterval]. +// [currentInterval - randomizationFactor * currentInterval, currentInterval + randomizationFactor * currentInterval]. func getRandomValueFromInterval(randomizationFactor, random float64, currentInterval time.Duration) time.Duration { + if randomizationFactor == 0 { + return currentInterval // make sure no randomness is used when randomizationFactor is 0. + } var delta = randomizationFactor * float64(currentInterval) var minInterval = float64(currentInterval) - delta var maxInterval = float64(currentInterval) + delta diff --git a/vendor/github.com/cenkalti/backoff/v4/retry.go b/vendor/github.com/cenkalti/backoff/v4/retry.go index 6c776ccf8e..b9c0c51cd7 100644 --- a/vendor/github.com/cenkalti/backoff/v4/retry.go +++ b/vendor/github.com/cenkalti/backoff/v4/retry.go @@ -1,11 +1,24 @@ package backoff -import "time" +import ( + "errors" + "time" +) + +// An OperationWithData is executing by RetryWithData() or RetryNotifyWithData(). +// The operation will be retried using a backoff policy if it returns an error. +type OperationWithData[T any] func() (T, error) // An Operation is executing by Retry() or RetryNotify(). // The operation will be retried using a backoff policy if it returns an error. type Operation func() error +func (o Operation) withEmptyData() OperationWithData[struct{}] { + return func() (struct{}, error) { + return struct{}{}, o() + } +} + // Notify is a notify-on-error function. It receives an operation error and // backoff delay if the operation failed (with an error). // @@ -25,18 +38,41 @@ func Retry(o Operation, b BackOff) error { return RetryNotify(o, b, nil) } +// RetryWithData is like Retry but returns data in the response too. +func RetryWithData[T any](o OperationWithData[T], b BackOff) (T, error) { + return RetryNotifyWithData(o, b, nil) +} + // RetryNotify calls notify function with the error and wait duration // for each failed attempt before sleep. func RetryNotify(operation Operation, b BackOff, notify Notify) error { return RetryNotifyWithTimer(operation, b, notify, nil) } +// RetryNotifyWithData is like RetryNotify but returns data in the response too. +func RetryNotifyWithData[T any](operation OperationWithData[T], b BackOff, notify Notify) (T, error) { + return doRetryNotify(operation, b, notify, nil) +} + // RetryNotifyWithTimer calls notify function with the error and wait duration using the given Timer // for each failed attempt before sleep. // A default timer that uses system timer is used when nil is passed. func RetryNotifyWithTimer(operation Operation, b BackOff, notify Notify, t Timer) error { - var err error - var next time.Duration + _, err := doRetryNotify(operation.withEmptyData(), b, notify, t) + return err +} + +// RetryNotifyWithTimerAndData is like RetryNotifyWithTimer but returns data in the response too. +func RetryNotifyWithTimerAndData[T any](operation OperationWithData[T], b BackOff, notify Notify, t Timer) (T, error) { + return doRetryNotify(operation, b, notify, t) +} + +func doRetryNotify[T any](operation OperationWithData[T], b BackOff, notify Notify, t Timer) (T, error) { + var ( + err error + next time.Duration + res T + ) if t == nil { t = &defaultTimer{} } @@ -49,16 +85,22 @@ func RetryNotifyWithTimer(operation Operation, b BackOff, notify Notify, t Timer b.Reset() for { - if err = operation(); err == nil { - return nil + res, err = operation() + if err == nil { + return res, nil } - if permanent, ok := err.(*PermanentError); ok { - return permanent.Err + var permanent *PermanentError + if errors.As(err, &permanent) { + return res, permanent.Err } if next = b.NextBackOff(); next == Stop { - return err + if cerr := ctx.Err(); cerr != nil { + return res, cerr + } + + return res, err } if notify != nil { @@ -69,7 +111,7 @@ func RetryNotifyWithTimer(operation Operation, b BackOff, notify Notify, t Timer select { case <-ctx.Done(): - return ctx.Err() + return res, ctx.Err() case <-t.C(): } } @@ -88,8 +130,16 @@ func (e *PermanentError) Unwrap() error { return e.Err } +func (e *PermanentError) Is(target error) bool { + _, ok := target.(*PermanentError) + return ok +} + // Permanent wraps the given err in a *PermanentError. -func Permanent(err error) *PermanentError { +func Permanent(err error) error { + if err == nil { + return nil + } return &PermanentError{ Err: err, } diff --git a/vendor/github.com/cenkalti/backoff/v4/ticker.go b/vendor/github.com/cenkalti/backoff/v4/ticker.go index ed699e0e30..df9d68bce5 100644 --- a/vendor/github.com/cenkalti/backoff/v4/ticker.go +++ b/vendor/github.com/cenkalti/backoff/v4/ticker.go @@ -33,6 +33,9 @@ func NewTicker(b BackOff) *Ticker { // NewTickerWithTimer returns a new Ticker with a custom timer. // A default timer that uses system timer is used when nil is passed. func NewTickerWithTimer(b BackOff, timer Timer) *Ticker { + if timer == nil { + timer = &defaultTimer{} + } c := make(chan time.Time) t := &Ticker{ C: c, diff --git a/vendor/modules.txt b/vendor/modules.txt index d18a70c627..961a0f8c92 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -89,8 +89,8 @@ github.com/aws/aws-sdk-go/service/sts/stsiface # github.com/beorn7/perks v1.0.1 ## explicit; go 1.11 github.com/beorn7/perks/quantile -# github.com/cenkalti/backoff/v4 v4.0.0 -## explicit; go 1.12 +# github.com/cenkalti/backoff/v4 v4.2.1 +## explicit; go 1.18 github.com/cenkalti/backoff/v4 # github.com/cespare/xxhash/v2 v2.1.1 ## explicit; go 1.11