Documentation
¶
Index ¶
Examples ¶
Constants ¶
Variables ¶
var ( // ErrMaxRetry is returned by [Retryer.RunContext] when the retryable // function did not succeed within MaxRetry attempts. ErrMaxRetry = errors.New("go-backoff/backoff: max retry count reached") // ErrTimeout is returned by [Retryer.RunContext] when MaxElapsedTime // is reached before the retryable function succeeds. ErrTimeout = errors.New("go-backoff/backoff: max elapsed time reached") )
Functions ¶
This section is empty.
Types ¶
type Backoff ¶
type Backoff interface {
// Attempt returns the n-th backoff duration.
// Returned duration can be zero or positive.
// n<=0 always returns zero.
Attempt(n int) time.Duration
}
Backoff provides backoff algorithm.
type Error ¶
type Error struct {
Inner error // Inner is the inner error.
Type string // Type is the error type.
Alg string // Alg is the backoff algorithm.
Msg string // Msg is the error message.
}
Error is the backoff error.
type Exponential ¶
type Exponential struct {
// contains filtered or unexported fields
}
Exponential provides exponential backoff strategy.
Example ¶
package main
import (
"fmt"
"time"
"github.com/aileron-projects/go-backoff"
)
func main() {
exponential := &backoff.ExponentialConfig{
Offset: 0 * time.Millisecond,
Limit: 600 * time.Second,
Coeff: 1 * time.Millisecond,
Base: 1.2,
Jitter: backoff.NoJitter,
}
bo, err := exponential.New()
if err != nil {
panic(err)
}
for i := range 11 {
d := bo.Attempt(i)
fmt.Printf("%03d: %s\n", i, d)
}
}
Output: 000: 0s 001: 1.2ms 002: 1.44ms 003: 1.728ms 004: 2.0736ms 005: 2.48832ms 006: 2.985983ms 007: 3.58318ms 008: 4.299816ms 009: 5.15978ms 010: 6.191736ms
type ExponentialConfig ¶ added in v0.0.2
type ExponentialConfig struct {
// Offset is a constant duration added to every backoff.
// Must be >= 0.
// Zero value (default): no offset is added.
Offset time.Duration
// Limit caps the maximum backoff duration.
// Must be >= Offset.
// Zero value (default): no upper limit is applied.
Limit time.Duration
// Coeff is the coefficient multiplied by Base^n.
// Must be >= 0.
// Zero value (default): 1 millisecond.
Coeff time.Duration
// Base is the base number applied to the attempt number n.
// Must be >= 1.
// Zero value (default): 2.0.
Base float64
// Jitter controls how much random fluctuation is added to the
// backoff duration, in the range [0.0, 1.0]:
// - 0.0: no jitter
// - 0.5: half jitter
// - 1.0: full jitter
// Zero value (default): 0.0 (no jitter).
Jitter float64
}
ExponentialConfig is the configuration for Exponential.
Backoff duration for the n-th attempt with no jitter is:
d = offset + coeff * base^n
Each field has a zero-value default as described below, so a ExponentialConfig can be constructed with only the fields that need to differ from the defaults.
func (*ExponentialConfig) New ¶ added in v0.0.2
func (c *ExponentialConfig) New() (*Exponential, error)
type Fibonacci ¶
type Fibonacci struct {
// contains filtered or unexported fields
}
Fibonacci provides fibonacci backoff strategy.
Example ¶
package main
import (
"fmt"
"time"
"github.com/aileron-projects/go-backoff"
)
func main() {
fibonacci := &backoff.FibonacciConfig{
Offset: 0 * time.Millisecond,
Limit: 600 * time.Second,
Coeff: 500 * time.Microsecond,
Jitter: backoff.NoJitter,
}
bo, err := fibonacci.New()
if err != nil {
panic(err)
}
for i := range 11 {
d := bo.Attempt(i)
fmt.Printf("%03d: %s\n", i, d)
}
}
Output: 000: 0s 001: 500µs 002: 500µs 003: 1ms 004: 1.5ms 005: 2.5ms 006: 4ms 007: 6.5ms 008: 10.5ms 009: 17ms 010: 27.5ms
type FibonacciConfig ¶ added in v0.0.2
type FibonacciConfig struct {
// Offset is a constant duration added to every backoff.
// Must be >= 0.
// Zero value (default): no offset is added.
Offset time.Duration
// Limit caps the maximum backoff duration.
// Must be >= Offset.
// Zero value (default): no upper limit is applied.
Limit time.Duration
// Coeff is the coefficient multiplied by fibonacci(n).
// Must be >= 0.
// Zero value (default): 1 millisecond.
Coeff time.Duration
// Jitter controls how much random fluctuation is added to the
// backoff duration, in the range [0.0, 1.0]:
// - 0.0: no jitter
// - 0.5: half jitter
// - 1.0: full jitter
// Zero value (default): 0.0 (no jitter).
Jitter float64
}
FibonacciConfig is the configuration for Fibonacci.
Backoff duration for the n-th attempt with no jitter is:
d = offset + coeff * fibonacci(n)
Each field has a zero-value default as described below, so a FibonacciConfig can be constructed with only the fields that need to differ from the defaults.
func (*FibonacciConfig) New ¶ added in v0.0.2
func (c *FibonacciConfig) New() (*Fibonacci, error)
type Fixed ¶
type Fixed struct {
// contains filtered or unexported fields
}
Fixed provides fixed-interval backoff strategy.
Example ¶
package main
import (
"fmt"
"time"
"github.com/aileron-projects/go-backoff"
)
func main() {
fixed := &backoff.FixedConfig{
Interval: 100 * time.Millisecond,
}
bo, err := fixed.New()
if err != nil {
panic(err)
}
for i := range 11 {
d := bo.Attempt(i)
fmt.Printf("%03d: %s\n", i, d)
}
}
Output: 000: 0s 001: 100ms 002: 100ms 003: 100ms 004: 100ms 005: 100ms 006: 100ms 007: 100ms 008: 100ms 009: 100ms 010: 100ms
type FixedConfig ¶ added in v0.0.2
type FixedConfig struct {
// Interval is a constant duration of every backoff.
// Must be >= 0.
// Zero value (default): 1 second.
Interval time.Duration
}
FixedConfig is the configuration for Fixed.
Backoff duration for the n-th attempt is:
d = interval
Each field has a zero-value default as described below, so a FixedConfig can be constructed with only the fields that need to differ from the defaults.
func (*FixedConfig) New ¶ added in v0.0.2
func (c *FixedConfig) New() (*Fixed, error)
type Linear ¶
type Linear struct {
// contains filtered or unexported fields
}
Linear provides linear backoff strategy.
Example ¶
package main
import (
"fmt"
"time"
"github.com/aileron-projects/go-backoff"
)
func main() {
linear := &backoff.LinearConfig{
Offset: 0 * time.Millisecond,
Limit: 200 * time.Millisecond,
Coeff: 5 * time.Millisecond,
Jitter: backoff.NoJitter,
}
bo, err := linear.New()
if err != nil {
panic(err)
}
for i := range 11 {
d := bo.Attempt(i)
fmt.Printf("%03d: %s\n", i, d)
}
}
Output: 000: 0s 001: 5ms 002: 10ms 003: 15ms 004: 20ms 005: 25ms 006: 30ms 007: 35ms 008: 40ms 009: 45ms 010: 50ms
type LinearConfig ¶ added in v0.0.2
type LinearConfig struct {
// Offset is a constant duration added to every backoff.
// Must be >= 0.
// Zero value (default): no offset is added.
Offset time.Duration
// Limit caps the maximum backoff duration.
// Must be >= Offset.
// Zero value (default): no upper limit is applied.
Limit time.Duration
// Coeff is the coefficient multiplied by n.
// Must be >= 0.
// Zero value (default): 1 second.
Coeff time.Duration
// Jitter controls how much random fluctuation is added to the
// backoff duration, in the range [0.0, 1.0]:
// - 0.0: no jitter
// - 0.5: half jitter
// - 1.0: full jitter
// Zero value (default): 0.0 (no jitter).
Jitter float64
}
LinearConfig is the configuration for Linear.
Backoff duration for the n-th attempt with no jitter is:
d = offset + coeff * n
Each field has a zero-value default as described below, so a LinearConfig can be constructed with only the fields that need to differ from the defaults.
func (*LinearConfig) New ¶ added in v0.0.2
func (c *LinearConfig) New() (*Linear, error)
type Notify ¶
type Notify struct {
// contains filtered or unexported fields
}
Notify reports the outcome of a retryable function to the retryer. The retryer stops retrying when either Stop or Success is called.
func (*Notify) RetryCount ¶ added in v0.0.2
RetryCount returns the count of retry. 0 for first run. n>=1 for n-th retry.
type Polynomial ¶
type Polynomial struct {
// contains filtered or unexported fields
}
Polynomial provides polynomial backoff strategy.
Example ¶
package main
import (
"fmt"
"time"
"github.com/aileron-projects/go-backoff"
)
func main() {
polynomial := &backoff.PolynomialConfig{
Offset: 0 * time.Millisecond,
Limit: 600 * time.Second,
Coeff: 10 * time.Millisecond,
Exponent: 2.0,
Jitter: backoff.NoJitter,
}
bo, err := polynomial.New()
if err != nil {
panic(err)
}
for i := range 11 {
d := bo.Attempt(i)
fmt.Printf("%03d: %s\n", i, d)
}
}
Output: 000: 0s 001: 10ms 002: 40ms 003: 90ms 004: 160ms 005: 250ms 006: 360ms 007: 490ms 008: 640ms 009: 810ms 010: 1s
type PolynomialConfig ¶ added in v0.0.2
type PolynomialConfig struct {
// Offset is a constant duration added to every backoff.
// Must be >= 0.
// Zero value (default): no offset is added.
Offset time.Duration
// Limit caps the maximum backoff duration.
// Must be >= Offset.
// Zero value (default): no upper limit is applied.
Limit time.Duration
// Coeff is the coefficient multiplied by n^Exponent.
// Must be >= 0.
// Zero value (default): 1 millisecond.
Coeff time.Duration
// Exponent is the exponent applied to the attempt number n.
// Must be >= 0.
// Zero value (default): 2.0.
Exponent float64
// Jitter controls how much random fluctuation is added to the
// backoff duration, in the range [0.0, 1.0]:
// - 0.0: no jitter
// - 0.5: half jitter
// - 1.0: full jitter
// Zero value (default): 0.0 (no jitter).
Jitter float64
}
PolynomialConfig is the configuration for Polynomial.
Backoff duration for the n-th attempt with no jitter is:
d = offset + coeff * n^exponent
Each field has a zero-value default as described below, so a PolynomialConfig can be constructed with only the fields that need to differ from the defaults.
func (*PolynomialConfig) New ¶ added in v0.0.2
func (c *PolynomialConfig) New() (*Polynomial, error)
type Random ¶
type Random struct {
// contains filtered or unexported fields
}
Random provides random backoff strategy.
Example ¶
package main
import (
"fmt"
"time"
"github.com/aileron-projects/go-backoff"
)
func main() {
random := &backoff.RandomConfig{
Offset: 0 * time.Millisecond,
Limit: 100 * time.Millisecond,
}
bo, err := random.New()
if err != nil {
panic(err)
}
for i := range 11 {
d := bo.Attempt(i)
fmt.Printf("%03d: %s\n", i, d)
}
}
Output:
type RandomConfig ¶ added in v0.0.2
type RandomConfig struct {
// Offset is a constant duration added to every backoff.
// Must be >= 0.
// Zero value (default): no offset is added.
Offset time.Duration
// Limit caps the maximum backoff duration.
// Must be >= Offset.
// Zero value (default): 1 second.
Limit time.Duration
}
RandomConfig is the configuration for Random.
Backoff duration for the n-th attempt is:
d = offset + random(limit-offset)
Each field has a zero-value default as described below, so a RandomConfig can be constructed with only the fields that need to differ from the defaults.
func (*RandomConfig) New ¶ added in v0.0.2
func (c *RandomConfig) New() (*Random, error)
type Retryer ¶
type Retryer struct {
// MaxRetry specifies the maximum number of retries.
// The retryable function is executed at most MaxRetry + 1 times.
// A value of zero or less disables retries.
MaxRetry int
// MaxElapsedTime specifies the maximum duration allowed for retries.
// The duration starts when Run or RunContext is called.
// It does not cancel a retryable function that is already running.
MaxElapsedTime time.Duration
// contains filtered or unexported fields
}
Retryer runs retryable functions with the backoff algorithm.
Example (Stop) ¶
package main
import (
"errors"
"fmt"
"time"
"github.com/aileron-projects/go-backoff"
)
func main() {
bo, err := (&backoff.FixedConfig{10 * time.Millisecond}).New()
if err != nil {
panic(err)
}
r := backoff.NewRetryer(bo)
r.MaxRetry = 100
r.MaxElapsedTime = 0 // No timeout
err = r.Run(func(n *backoff.Notify) error {
count := n.RetryCount()
fmt.Printf("%d-th call\n", count)
if count == 3 {
n.Stop()
fmt.Println("stop !!")
return errors.New("Err-stop")
}
return fmt.Errorf("Err-%d", count)
})
fmt.Println("----- Error -----")
fmt.Println(err)
}
Output: 0-th call 1-th call 2-th call 3-th call stop !! ----- Error ----- Err-0 Err-1 Err-2 Err-stop
Example (Success) ¶
package main
import (
"fmt"
"time"
"github.com/aileron-projects/go-backoff"
)
func main() {
bo, err := (&backoff.FixedConfig{10 * time.Millisecond}).New()
if err != nil {
panic(err)
}
r := backoff.NewRetryer(bo)
r.MaxRetry = 100
r.MaxElapsedTime = 0 // No timeout
err = r.Run(func(n *backoff.Notify) error {
count := n.RetryCount()
fmt.Printf("%d-th call\n", count)
if count == 3 {
n.Success()
fmt.Println("success !!")
return nil
}
return fmt.Errorf("Err-%d", count)
})
fmt.Println("----- Error -----")
fmt.Println(err)
}
Output: 0-th call 1-th call 2-th call 3-th call success !! ----- Error ----- <nil>
func NewRetryer ¶
NewRetryer creates a new Retryer with the given backoff. Returned retryer has no retry and has no timeout. It uses (&RandomConfig{Limit: time.Second}).New() when nil is given.
func (*Retryer) RunContext ¶
RunContext executes the retryable function with the configured backoff strategy. It returns nil if Notify.Success is called. It returns the errors returned by the retryable function joined with errors.Join if Notify.Stop is called. It returns an error wrapping ctx.Err() and all errors returned so far by the retryable function if ctx is canceled or its deadline is exceeded while waiting for the next attempt. It returns an error wrapping ErrTimeout and all errors returned by the retryable function if MaxElapsedTime is reached. It returns an error wrapping ErrMaxRetry and all errors returned by the retryable function if MaxRetry is reached.
Directories
¶
| Path | Synopsis |
|---|---|
|
exponential
command
|
|
|
fibonacci
command
|
|
|
fixed
command
|
|
|
linear
command
|
|
|
polynomial
command
|
|
|
random
command
|
|
|
retry
command
|