Documentation
¶
Index ¶
Examples ¶
Constants ¶
const ( NoJitter float64 = 0.0 FullJitter float64 = 1.0 EqualJitter float64 = 0.5 HalfJitter float64 = 0.5 QuaterJitter float64 = 0.25 )
const NoLimit = time.Duration(math.MaxInt64)
NoLimit is the alias for MaxInt64 in time.Duration. It is the actual limit of durations.
Variables ¶
var ( ErrMaxRetry = errors.New("go-backoff/backoff: max retry count reached") 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() {
// Parameters
offset := 0 * time.Millisecond
limit := 600 * time.Second
coeff := 1 * time.Millisecond
base := 1.2
jitter := backoff.NoJitter
// Instanciate a backoff provider.
bo, err := backoff.NewExponential(offset, limit, coeff, base, jitter)
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
func NewExponential ¶
func NewExponential(offset, limit, coeff time.Duration, base, jitter float64) (*Exponential, error)
NewExponential returns a new instance of Exponential.
- offset: offset for the backoff duration. (>=0)
- limit: maximum backoff duration. (>=offset)
- coeff: coefficient for exponential function. (>=0)
- base: base number for exponential function. (>=1)
- jitter: parameter for random fluctuation. 1.0 for full jitter. (>=0.0, <=1.0)
Backoff duration for n-th attempt with no jitter will be:
d = offset + coeff * base^n
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() {
// Parameters
offset := 0 * time.Millisecond
limit := 600 * time.Second
coeff := 500 * time.Microsecond
jitter := backoff.NoJitter
// Instanciate a backoff provider.
bo, err := backoff.NewFibonacci(offset, limit, coeff, jitter)
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
func NewFibonacci ¶
NewFibonacci returns a new instance of Fibonacci.
- offset: offset for the backoff duration. (>=0)
- limit: maximum backoff duration. (>=offset)
- coeff: coefficient for fibonacci number. (>=0)
- jitter: parameter for random fluctuation. 1.0 for full jitter. (>=0.0, <=1.0)
Backoff duration for n-th attempt with no jitter will be:
d = offset + coeff * fibonacci(n)
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() {
// Parameters
interval := 100 * time.Millisecond
// Instanciate a backoff provider.
bo, err := backoff.NewFixed(interval)
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 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() {
// Parameters
offset := 0 * time.Millisecond
limit := 200 * time.Millisecond
coeff := 5 * time.Millisecond
jitter := backoff.NoJitter
// Instanciate a backoff provider.
bo, err := backoff.NewLinear(offset, limit, coeff, jitter)
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
func NewLinear ¶
NewLinear returns a new instance of Linear.
- offset: offset for the backoff duration. (>=0)
- limit: maximum backoff duration. (>=offset)
- coeff: coefficient for linear function. (>=0)
- jitter: parameter for random fluctuation. 1.0 for full jitter. (>=0.0, <=1.0)
Backoff duration for n-th attempt with no jitter will be:
d = offset + coeff * (n)
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.
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() {
// Parameters
offset := 0 * time.Millisecond
limit := 600 * time.Second
coeff := 10 * time.Millisecond
exponent := 2.0
jitter := backoff.NoJitter
// Instanciate a backoff provider.
bo, err := backoff.NewPolynomial(offset, limit, coeff, exponent, jitter)
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
func NewPolynomial ¶
func NewPolynomial(offset, limit, coeff time.Duration, exponent, jitter float64) (*Polynomial, error)
NewPolynomial returns a new instance of Polynomial.
- offset: offset for the backoff duration. (>=0)
- limit: maximum backoff duration. (>=offset)
- coeff: coefficient for polynomial function. (>=0)
- exponent: exponent of n. (>=0)
- jitter: parameter for random fluctuation. 1.0 for full jitter. (>=0.0, <=1.0)
Backoff duration for n-th attempt with no jitter will be:
d = offset + coeff * n^exponent
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() {
// Parameters
offset := 0 * time.Millisecond
limit := 100 * time.Millisecond
// Instanciate a backoff provider.
bo, err := backoff.NewRandom(offset, limit)
if err != nil {
panic(err)
}
for i := range 11 {
d := bo.Attempt(i)
fmt.Printf("%03d: %s\n", i, d)
}
}
Output:
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.NewFixed(10 * time.Millisecond)
if err != nil {
panic(err)
}
r := backoff.NewRetryer(bo)
r.MaxRetry = 100
r.MaxElapsedTime = 0 // No timeout
counter := 0
err = r.Run(func(n *backoff.Notify) error {
counter++
fmt.Printf("%d-th call\n", counter)
if counter == 3 {
n.Stop()
fmt.Println("stop !!")
return errors.New("Err-stop")
}
return fmt.Errorf("Err-%d", counter)
})
fmt.Println("----- Error -----")
fmt.Println(err)
}
Output: 1-th call 2-th call 3-th call stop !! ----- Error ----- Err-1 Err-2 Err-stop
Example (Success) ¶
package main
import (
"fmt"
"time"
"github.com/aileron-projects/go-backoff"
)
func main() {
bo, err := backoff.NewFixed(10 * time.Millisecond)
if err != nil {
panic(err)
}
r := backoff.NewRetryer(bo)
r.MaxRetry = 100
r.MaxElapsedTime = 0 // No timeout
counter := 0
err = r.Run(func(n *backoff.Notify) error {
counter++
fmt.Printf("%d-th call\n", counter)
if counter == 3 {
n.Success()
fmt.Println("success !!")
return nil
}
return fmt.Errorf("Err-%d", counter)
})
fmt.Println("----- Error -----")
fmt.Println(err)
}
Output: 1-th call 2-th call 3-th call success !! ----- Error ----- <nil>
func NewRetryer ¶
NewRetryer creates a new Retryer with given backoff. Returned retryer has no retry and has no timeout. It uses NewRandom(0, time.Second) when nil was 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 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
|