Documentation ¶
Overview ¶
Simple library for retry mechanism
Slightly inspired by [Try::Tiny::Retry](https://metacpan.org/pod/Try::Tiny::Retry)
SYNOPSIS ¶
HTTP GET with retry:
url := "http://example.com" var body []byte err := retry.Do( func() error { resp, err := http.Get(url) if err != nil { return err } defer resp.Body.Close() body, err = ioutil.ReadAll(resp.Body) if err != nil { return err } return nil }, ) if err != nil { // handle error } fmt.Println(string(body))
HTTP GET with retry with data:
url := "http://example.com" body, err := retry.DoWithData( func() ([]byte, error) { resp, err := http.Get(url) if err != nil { return nil, err } defer resp.Body.Close() body, err := ioutil.ReadAll(resp.Body) if err != nil { return nil, err } return body, nil }, ) if err != nil { // handle error } fmt.Println(string(body))
[More examples](https://github.com/avast/retry-go/tree/master/examples)
SEE ALSO ¶
* giantswarm/retry-go(https://github.com/giantswarm/retry-go) - slightly complicated interface.
* sethgrid/pester(https://github.com/sethgrid/pester) - only http retry for http calls with retries and backoff
* cenkalti/backoff(https://github.com/cenkalti/backoff) - Go port of the exponential backoff algorithm from Google's HTTP Client Library for Java. Really complicated interface.
* rafaeljesus/retry-go(https://github.com/rafaeljesus/retry-go) - looks good, slightly similar as this package, don't have 'simple' `Retry` method
* matryer/try(https://github.com/matryer/try) - very popular package, nonintuitive interface (for me)
BREAKING CHANGES ¶
* 4.0.0
- infinity retry is possible by set `Attempts(0)` by PR [#49](https://github.com/avast/retry-go/pull/49)
* 3.0.0
- `DelayTypeFunc` accepts a new parameter `err` - this breaking change affects only your custom Delay Functions. This change allow [make delay functions based on error](examples/delay_based_on_error_test.go).
* 1.0.2 -> 2.0.0
- argument of `retry.Delay` is final delay (no multiplication by `retry.Units` anymore)
- function `retry.Units` are removed
- [more about this breaking change](https://github.com/avast/retry-go/issues/7)
* 0.3.0 -> 1.0.0
- `retry.Retry` function are changed to `retry.Do` function
- `retry.RetryCustom` (OnRetry) and `retry.RetryCustomWithOpts` functions are now implement via functions produces Options (aka `retry.OnRetry`)
Index ¶
- func BackOffDelay(n uint, _ error, config *Config) time.Duration
- func Do(retryableFunc RetryableFunc, opts ...Option) error
- func DoWithData[T any](retryableFunc RetryableFuncWithData[T], opts ...Option) (T, error)
- func FixedDelay(_ uint, _ error, config *Config) time.Duration
- func IsRecoverable(err error) bool
- func RandomDelay(_ uint, _ error, config *Config) time.Duration
- func Unrecoverable(err error) error
- type Config
- type DelayTypeFunc
- type Error
- type OnRetryFunc
- type Option
- func Attempts(attempts uint) Option
- func AttemptsForError(attempts uint, err error) Option
- func Context(ctx context.Context) Option
- func Delay(delay time.Duration) Option
- func DelayType(delayType DelayTypeFunc) Option
- func LastErrorOnly(lastErrorOnly bool) Option
- func MaxDelay(maxDelay time.Duration) Option
- func MaxJitter(maxJitter time.Duration) Option
- func OnRetry(onRetry OnRetryFunc) Option
- func RetryIf(retryIf RetryIfFunc) Option
- func UntilSucceeded() Option
- func WithTimer(t Timer) Option
- func WrapContextErrorWithLastError(wrapContextErrorWithLastError bool) Option
- type RetryIfFunc
- type RetryableFunc
- type RetryableFuncWithData
- type Timer
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func BackOffDelay ¶
BackOffDelay is a DelayType which increases delay between consecutive retries
func Do ¶
func Do(retryableFunc RetryableFunc, opts ...Option) error
func DoWithData ¶ added in v4.4.0
func DoWithData[T any](retryableFunc RetryableFuncWithData[T], opts ...Option) (T, error)
func FixedDelay ¶
FixedDelay is a DelayType which keeps delay the same through all iterations
func IsRecoverable ¶
IsRecoverable checks if error is an instance of `unrecoverableError`
func RandomDelay ¶
RandomDelay is a DelayType which picks a random delay up to config.maxJitter
func Unrecoverable ¶
Unrecoverable wraps an error in `unrecoverableError` struct
Types ¶
type DelayTypeFunc ¶
DelayTypeFunc is called to return the next delay to wait after the retriable function fails on `err` after `n` attempts.
func CombineDelay ¶
func CombineDelay(delays ...DelayTypeFunc) DelayTypeFunc
CombineDelay is a DelayType the combines all of the specified delays into a new DelayTypeFunc
type Error ¶
type Error []error
Error type represents list of errors in retry
func (Error) Error ¶
Error method return string representation of Error It is an implementation of error interface
func (Error) Unwrap ¶ added in v4.2.0
Unwrap the last error for compatibility with `errors.Unwrap()`. When you need to unwrap all errors, you should use `WrappedErrors()` instead.
err := Do( func() error { return errors.New("original error") }, Attempts(1), ) fmt.Println(errors.Unwrap(err)) # "original error" is printed
Added in version 4.2.0.
func (Error) WrappedErrors ¶
WrappedErrors returns the list of errors that this Error is wrapping. It is an implementation of the `errwrap.Wrapper` interface in package [errwrap](https://github.com/hashicorp/errwrap) so that `retry.Error` can be used with that library.
type OnRetryFunc ¶
Function signature of OnRetry function
type Option ¶
type Option func(*Config)
Option represents an option for retry.
func Attempts ¶
Attempts set count of retry. Setting to 0 will retry until the retried function succeeds. default is 10
func AttemptsForError ¶ added in v4.3.0
AttemptsForError sets count of retry in case execution results in given `err` Retries for the given `err` are also counted against total retries. The retry will stop if any of given retries is exhausted.
added in 4.3.0
func Context ¶
Context allow to set context of retry default are Background context
example of immediately cancellation (maybe it isn't the best example, but it describes behavior enough; I hope)
ctx, cancel := context.WithCancel(context.Background()) cancel() retry.Do( func() error { ... }, retry.Context(ctx), )
func DelayType ¶
func DelayType(delayType DelayTypeFunc) Option
DelayType set type of the delay between retries default is BackOff
func LastErrorOnly ¶
return the direct last error that came from the retried function default is false (return wrapped errors with everything)
func OnRetry ¶
func OnRetry(onRetry OnRetryFunc) Option
OnRetry function callback are called each retry
log each retry example:
retry.Do( func() error { return errors.New("some error") }, retry.OnRetry(func(n uint, err error) { log.Printf("#%d: %s\n", n, err) }), )
func RetryIf ¶
func RetryIf(retryIf RetryIfFunc) Option
RetryIf controls whether a retry should be attempted after an error (assuming there are any retry attempts remaining)
skip retry if special error example:
retry.Do( func() error { return errors.New("special error") }, retry.RetryIf(func(err error) bool { if err.Error() == "special error" { return false } return true }) )
By default RetryIf stops execution if the error is wrapped using `retry.Unrecoverable`, so above example may also be shortened to:
retry.Do( func() error { return retry.Unrecoverable(errors.New("special error")) } )
func UntilSucceeded ¶ added in v4.6.0
func UntilSucceeded() Option
UntilSucceeded will retry until the retried function succeeds. Equivalent to setting Attempts(0).
func WithTimer ¶ added in v4.1.0
WithTimer provides a way to swap out timer module implementations. This primarily is useful for mocking/testing, where you may not want to explicitly wait for a set duration for retries.
example of augmenting time.After with a print statement
type struct MyTimer {} func (t *MyTimer) After(d time.Duration) <- chan time.Time { fmt.Print("Timer called!") return time.After(d) } retry.Do( func() error { ... }, retry.WithTimer(&MyTimer{}) )
func WrapContextErrorWithLastError ¶ added in v4.5.0
WrapContextErrorWithLastError allows the context error to be returned wrapped with the last error that the retried function returned. This is only applicable when Attempts is set to 0 to retry indefinitly and when using a context to cancel / timeout
default is false
ctx, cancel := context.WithCancel(context.Background()) defer cancel() retry.Do( func() error { ... }, retry.Context(ctx), retry.Attempts(0), retry.WrapContextErrorWithLastError(true), )
type RetryableFuncWithData ¶ added in v4.4.0
Function signature of retryable function with data