Documentation
¶
Overview ¶
Package backoff provides iterators powered by github.com/cenkalti/backoff/v4.
This package provides the type BackOff and BackOffDuration, which creates an iterator powered by github.com/cenkalti/backoff/v4.
BackOff is used to configure a run-and-wait loop, and BackOffDuration is used to generate a sequence of wait times.
BackOff can be created by NewConstant and NewExponential.
BackOffDuration can be created by NewConstantDuration and NewExponentialDuration.
There are four policies.
Iteratros powered by StopBackOff, ZeroBackOff and ConstantBackOff can be created from NewConstant and NewConstantDuration.
Iterators powered by ExponentialBackOff can be created from NewExponential and NewExponentialDuration.
Iterators are used in `for statements with range clause` so that iteration can be easily terminated with `break`. Alternatively, you can use WithMaxRetries to limit the number of retries.
You can interrupt the wait by canceling the context you specified when creating the iterator, idiomatically.
See ¶
Example ¶
package main import ( "context" "fmt" "time" "github.com/goaux/backoff" ) func main() { ctx := context.TODO() unit := 100 * time.Millisecond // [ExponentialBackOff](https://pkg.go.dev/github.com/cenkalti/backoff/v4#ExponentialBackOff) exponentialBackOff := backoff.NewExponential( backoff.WithInitialInterval(unit), backoff.WithRandomizationFactor(0), // Set to 0 for demonstrative purpose. backoff.WithMaxRetries(7), ) start := time.Now() for i := range exponentialBackOff(ctx) { fmt.Println("task", i, (time.Since(start) / unit * unit).String()) if false { // Here we assume the task will always fail, so no break will occur. break } } }
Output: task 0 0s task 1 100ms task 2 200ms task 3 400ms task 4 800ms task 5 1.3s task 6 2s task 7 3.2s
Index ¶
- type BackOff
- type BackOffDuration
- type ConstantOption
- type ExponentialOption
- func WithClockProvider(c backoff.Clock) ExponentialOption
- func WithInitialInterval(d time.Duration) ExponentialOption
- func WithMaxElapsedTime(d time.Duration) ExponentialOption
- func WithMaxInterval(d time.Duration) ExponentialOption
- func WithMultiplier(v float64) ExponentialOption
- func WithRandomizationFactor(v float64) ExponentialOption
- func WithRetryStopDuration(d time.Duration) ExponentialOption
- type Option
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type BackOff ¶
BackOff is a function to create an iterator. The iterator can be cancelled by a context. It is safe to pass nil for the context when creating an iterator. The iterator yields sequence of integers representing the number of retry attempts.
func NewConstant ¶
func NewConstant(interval time.Duration, options ...ConstantOption) BackOff
NewConstant returns a BackOff, which creates an iterator with a backoff policy that always returns the same backoff delay.
If interval < 0 then NewConstant returns the iterator powered by backoff.StopBackOff.
If interval == 0 then NewConstant returns the iterator powered by backoff.ZeroBackOff.
If interval > 0 then NewConstant returns the iterator powered by backoff.ConstantBackOff.
Example ¶
package main import ( "context" "fmt" "time" "github.com/goaux/backoff" ) func main() { ctx := context.TODO() unit := 100 * time.Millisecond // interval > 0 // [ConstantBackOff](https://pkg.go.dev/github.com/cenkalti/backoff/v4#ConstantBackOff) constant := backoff.NewConstant(2*unit, backoff.WithMaxRetries(5)) start := time.Now() for i := range constant(ctx) { fmt.Println("constant#false", i, (time.Since(start) / unit * unit).String()) if false { break } } start = time.Now() for i := range constant(ctx) { fmt.Println("constant#true", i, (time.Since(start) / unit * unit).String()) if true { break } } }
Output: constant#false 0 0s constant#false 1 200ms constant#false 2 400ms constant#false 3 600ms constant#false 4 800ms constant#false 5 1s constant#true 0 0s
Example (CancelContext) ¶
package main import ( "context" "fmt" "time" "github.com/goaux/backoff" ) func main() { ctx := context.TODO() unit := 100 * time.Millisecond // interval > 0 // [ConstantBackOff](https://pkg.go.dev/github.com/cenkalti/backoff/v4#ConstantBackOff) constantBackOff := backoff.NewConstant(2*unit, backoff.WithMaxRetries(5)) start := time.Now() ctx, cancel := context.WithTimeout(ctx, 3*unit) defer cancel() for i := range constantBackOff(ctx) { fmt.Println("constant#false", i, (time.Since(start) / unit * unit).String()) if false { break } } fmt.Println("cancel", (time.Since(start) / unit * unit).String()) }
Output: constant#false 0 0s constant#false 1 200ms cancel 300ms
Example (StopBackOff) ¶
package main import ( "context" "fmt" "time" "github.com/goaux/backoff" ) func main() { ctx := context.TODO() unit := 100 * time.Millisecond // interval < 0 // [StopBackOff](https://pkg.go.dev/github.com/cenkalti/backoff/v4#StopBackOff) constantBackOff := backoff.NewConstant(-1, backoff.WithMaxRetries(3)) start := time.Now() for i := range constantBackOff(ctx) { fmt.Println("stop#false", i, (time.Since(start) / unit * unit).String()) if false { break } } start = time.Now() for i := range constantBackOff(ctx) { fmt.Println("stop#true", i, (time.Since(start) / unit * unit).String()) if true { break } } }
Output: stop#false 0 0s stop#true 0 0s
Example (ZeroBackOff) ¶
package main import ( "context" "fmt" "time" "github.com/goaux/backoff" ) func main() { ctx := context.TODO() unit := 100 * time.Millisecond // interval == 0 // [ZeroBackOff](https://pkg.go.dev/github.com/cenkalti/backoff/v4#ZeroBackOff) constantBackOff := backoff.NewConstant(0, backoff.WithMaxRetries(4)) start := time.Now() for i := range constantBackOff(ctx) { fmt.Println("zero#false", i, (time.Since(start) / unit * unit).String()) if false { break } } start = time.Now() for i := range constantBackOff(ctx) { fmt.Println("zero#true", i, (time.Since(start) / unit * unit).String()) if true { break } } }
Output: zero#false 0 0s zero#false 1 0s zero#false 2 0s zero#false 3 0s zero#false 4 0s zero#true 0 0s
func NewExponential ¶
func NewExponential(options ...ExponentialOption) BackOff
NewExponential returns a BackOff, which creates an iterator powered by backoff.ExponentialBackOff.
Example ¶
package main import ( "context" "fmt" "time" "github.com/goaux/backoff" ) func main() { ctx := context.TODO() unit := 50 * time.Millisecond // [ExponentialBackOff](https://pkg.go.dev/github.com/cenkalti/backoff/v4#ExponentialBackOff) exponentialBackOff := backoff.NewExponential( backoff.WithInitialInterval(2*unit), backoff.WithRandomizationFactor(0), // Set to 0 for demonstrative purpose. backoff.WithMaxRetries(7), ) start := time.Now() for i := range exponentialBackOff(ctx) { fmt.Println("exponential#false", i, (time.Since(start) / unit * unit).String()) if false { break } } start = time.Now() for i := range exponentialBackOff(ctx) { fmt.Println("exponential#true", i, (time.Since(start) / unit * unit).String()) if true { break } } }
Output: exponential#false 0 0s exponential#false 1 100ms exponential#false 2 250ms exponential#false 3 450ms exponential#false 4 800ms exponential#false 5 1.3s exponential#false 6 2.05s exponential#false 7 3.2s exponential#true 0 0s
Example (CancelContext) ¶
package main import ( "context" "fmt" "time" "github.com/goaux/backoff" ) func main() { ctx := context.TODO() unit := 50 * time.Millisecond // [ExponentialBackOff](https://pkg.go.dev/github.com/cenkalti/backoff/v4#ExponentialBackOff) exponentialBackOff := backoff.NewExponential( backoff.WithInitialInterval(2*unit), backoff.WithRandomizationFactor(0), // Set to 0 for demonstrative purpose. backoff.WithMaxRetries(7), ) start := time.Now() ctx, cancel := context.WithTimeout(ctx, 3*unit) defer cancel() for i := range exponentialBackOff(ctx) { fmt.Println("exponential#false", i, (time.Since(start) / unit * unit).String()) if false { break } } fmt.Println("cancel", (time.Since(start) / unit * unit).String()) }
Output: exponential#false 0 0s exponential#false 1 100ms cancel 150ms
type BackOffDuration ¶ added in v1.1.0
BackOffDuration is a function to create an iterator that emits interval durations.
func NewConstantDuration ¶ added in v1.1.0
func NewConstantDuration( interval time.Duration, options ...ConstantOption, ) BackOffDuration
NewConstantDuration returns a BackOffDuration, which creates an iterator with a backoff policy that always returns the same backoff delay.
If interval < 0 then NewConstantDuration returns the iterator powered by backoff.StopBackOff.
If interval == 0 then NewConstantDuration returns the iterator powered by backoff.ZeroBackOff.
If interval > 0 then NewConstantDuration returns the iterator powered by backoff.ConstantBackOff.
Example ¶
package main import ( "fmt" "time" "github.com/goaux/backoff" ) func main() { backOffDuration := backoff.NewConstantDuration(42*time.Second, backoff.WithMaxRetries(5)) for i, d := range backOffDuration() { fmt.Println(i, d.String()) } }
Output: 0 42s 1 42s 2 42s 3 42s 4 42s
func NewExponentialDuration ¶ added in v1.1.0
func NewExponentialDuration( options ...ExponentialOption, ) BackOffDuration
NewExponentialDuration returns a BackOffDuration, which creates an iterator powered by backoff.ExponentialBackOff.
Example ¶
package main import ( "fmt" "time" "github.com/goaux/backoff" ) func main() { backOffDuration := backoff.NewExponentialDuration( backoff.WithInitialInterval(10*time.Second), backoff.WithRandomizationFactor(0), backoff.WithMaxRetries(5), ) for i, d := range backOffDuration() { fmt.Println(i, d.String()) } }
Output: 0 10s 1 15s 2 22.5s 3 33.75s 4 50.625s
type ConstantOption ¶
type ConstantOption interface {
// contains filtered or unexported methods
}
ConstantOption is a optional parameter for NewConstant.
type ExponentialOption ¶
type ExponentialOption interface {
// contains filtered or unexported methods
}
ExponentialOption is a optional parameter for NewExponential.
The following options are available:
- WithInitialInterval: The initial interval for the first retry
- WithRandomizationFactor: The randomization factor to use for creating a range around the retry interval
- WithMultiplier: The factor by which the retry interval increases
- WithMaxInterval: The maximum value of the retry interval
- WithMaxElapsedTime: The maximum amount of time to retry
- WithRetryStopDuration: The interval at which the backoff stops increasing
- WithClockProvider: The clock to use for time measurements
See backoff.ExponentialBackOff for more details on each option.
func WithClockProvider ¶
func WithClockProvider(c backoff.Clock) ExponentialOption
WithClockProvider sets the clock used to measure time.
func WithInitialInterval ¶
func WithInitialInterval(d time.Duration) ExponentialOption
WithInitialInterval sets the initial interval between retries.
func WithMaxElapsedTime ¶
func WithMaxElapsedTime(d time.Duration) ExponentialOption
WithMaxElapsedTime sets the maximum total time for retries.
func WithMaxInterval ¶
func WithMaxInterval(d time.Duration) ExponentialOption
WithMaxInterval sets the maximum interval between retries.
func WithMultiplier ¶
func WithMultiplier(v float64) ExponentialOption
WithMultiplier sets the multiplier for increasing the interval after each retry.
func WithRandomizationFactor ¶
func WithRandomizationFactor(v float64) ExponentialOption
WithRandomizationFactor sets the randomization factor to add jitter to intervals.
func WithRetryStopDuration ¶
func WithRetryStopDuration(d time.Duration) ExponentialOption
WithRetryStopDuration sets the duration after which retries should stop.
type Option ¶
type Option interface { ConstantOption ExponentialOption }
Option is a optional parameter for NewConstant and NewExponential.
func WithMaxRetries ¶
WithMaxRetries sets the upper limit of the retry loop count.