Documentation ¶
Overview ¶
Package backoff implments backoff algorithms for retrying operations.
Users first create an appropriate `Policy` object, and when the operation that needs retrying is about to start, they kick the actual backoff
Example ¶
package main import ( "context" "errors" "time" backoff "github.com/lestrrat-go/backoff" ) func main() { p := backoff.NewConstant(time.Second) flakyFunc := func(a int) (int, error) { // silly function that only succeeds if the current call count is // divisible by either 3 or 5 but not both switch { case a%15 == 0: return 0, errors.New(`invalid`) case a%3 == 0 || a%5 == 0: return a, nil } return 0, errors.New(`invalid`) } ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() retryFunc := func(v int) (int, error) { b, cancel := p.Start(ctx) defer cancel() for { x, err := flakyFunc(v) if err == nil { return x, nil } select { case <-b.Done(): return 0, errors.New(`....`) case <-b.Next(): // no op, go to next } } } retryFunc(15) }
Output:
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Continue ¶
Continue is a convenience wrapper around the
Example ¶
package main import ( "context" "errors" "time" backoff "github.com/lestrrat-go/backoff" ) func main() { p := backoff.NewConstant(time.Second) flakyFunc := func(a int) (int, error) { // silly function that only succeeds if the current call count is // divisible by either 3 or 5 but not both switch { case a%15 == 0: return 0, errors.New(`invalid`) case a%3 == 0 || a%5 == 0: return a, nil } return 0, errors.New(`invalid`) } ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() retryFunc := func(v int) (int, error) { b, cancel := p.Start(ctx) defer cancel() for backoff.Continue(b) { x, err := flakyFunc(v) if err == nil { return x, nil } } return 0, errors.New(`failed to get value`) } retryFunc(15) }
Output:
func IsPermanentError ¶
IsPermanentError returns true if the given error is a permanent error. Permanent errors are those that implements the `PermanentError` interface and returns `true` for the `IsPermanent` method.
func MarkPermanent ¶
func Retry ¶
Retry is a convenience wrapper around the backoff algorithm. If your target operation can be nicely enclosed in the `Executer` interface, this will remove your need to write much of the boilerplate.
Example ¶
package main import ( "context" "errors" "log" "time" backoff "github.com/lestrrat-go/backoff" ) func main() { count := 0 e := backoff.ExecuteFunc(func(_ context.Context) error { // This is a silly example that succeeds on every 10th try count++ if count%10 == 0 { return nil } return errors.New(`dummy`) }) ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() p := backoff.NewExponential() if err := backoff.Retry(ctx, p, e); err != nil { log.Printf("failed to call function after repeated tries") } }
Output:
Types ¶
type CancelFunc ¶
type CancelFunc func()
type ExecuteFunc ¶
ExecuteFunc is an Executer that is represented by a single function
type Executer ¶
Executer represents an operation that can be performed within the Retry utility method.
type Exponential ¶
type Exponential struct {
// contains filtered or unexported fields
}
Exponential implements an exponential backoff policy.
func NewExponential ¶
func NewExponential(options ...Option) *Exponential
func (*Exponential) Start ¶
func (p *Exponential) Start(ctx context.Context) (Backoff, CancelFunc)
type Option ¶
type Option interface { Name() string Value() interface{} }
func WithFactor ¶
func WithInterval ¶
func WithJitterFactor ¶
func WithMaxElapsedTime ¶
WithMaxElapsedTime specifies the maximum amount of accumulative time that the backoff is allowed to wait before it is considered failed.
func WithMaxInterval ¶
WithMaxInterval specifies the maximum interval between retries, and is currently only applicable to exponential backoffs.
By default this is capped at 2 minutes. If you would like to change this value, you must explicitly specify it through this option.
If a value of 0 is specified, then there is no limit, and the backoff interval will keep increasing.
func WithMaxRetries ¶
WithMaxRetries specifies the maximum number of attempts that can be made by the backoff policies. By default each policy tries up to 10 times.
If you would like to retry forever, specify "0" and pass to the constructor of each policy.
func WithRetryForever ¶ added in v1.0.1
func WithRetryForever() Option
WithRetryForever is a short-hand for `WithMaxRetries(0)` -- well, ok, it's not a short-hand. But it makes reading the code just a tiny bit easier
type PermanentError ¶
type PermanentError interface {
IsPermanent() bool
}