Documentation
¶
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type ContextError ¶
type ContextError struct {
Err error
}
ContextError is an error returned by Tryer.Try wrapping the context error when the context is canceled.
func (ContextError) Error ¶
func (e ContextError) Error() string
func (ContextError) Unwrap ¶
func (e ContextError) Unwrap() error
type MaxTriesError ¶
type MaxTriesError struct {
Err error
}
MaxTriesError is an error returned by Tryer.Try wrapping the error returned by the function after the maximum number of tries is reached.
func (MaxTriesError) Error ¶
func (e MaxTriesError) Error() string
func (MaxTriesError) Unwrap ¶
func (e MaxTriesError) Unwrap() error
type Tryer ¶
type Tryer struct {
// Max is the maximum number of tries to make.
// [Tryer.Try] always makes at least one attempt.
// Leaving this set to 0 is the same as setting it to 1.
// A negative value means there is no limit on the number of attempts.
Max int
// Delay is the initial delay between attempts.
// Be sure to set this to a non-zero value to avoid an expensive busy loop.
// The delay can increase after each attempt; see the Scale field below.
Delay time.Duration
// Jitter is the maximum amount of random jitter to add to,
// or subtract from,
// the delay on each attempt.
// This value is silently limited to each iteration's delay.
Jitter time.Duration
// Scale increases the delay after each attempt, multiplying it by 1+Scale.
// For example, setting this to 1 will double the delay after each attempt.
// Leaving this set to 0 means the delay will not scale.
Scale float64
// MaxDelay is the maximum delay between attempts.
// Scale will not cause the delay to exceed this value.
// (However, random Jitter may still be added.)
// A value of 0 means there is no maximum delay.
MaxDelay time.Duration
// IsRetryable is an optional function that determines whether an error is retryable.
// If it is nil, all errors are considered retryable.
// It receives the context, the error, and the number of the next attempt (starting at 1).
IsRetryable func(context.Context, error, int) bool
// OnRetry is an optional function that is called after a retryable error in the callback.
// This can be used for logging or other side effects.
// It receives the context, the error, the number of the next attempt, and the delay before the next attempt.
OnRetry func(context.Context, error, int, time.Duration)
// After is an optional function returning a channel that sends the current time after the specified duration.
// If it is nil, [time.After] is used.
After func(time.Duration) <-chan time.Time
// Rand is an optional function that returns a random float64 in the range [0, 1).
// If it is nil, [rand.Float64] is used.
Rand func() float64
}
Tryer runs a function via its Try method one or more times until it succeeds, or a maximum number of retries is reached, or it encounters an unretryable error.
It waits for a specified interval between attempts, optionally adding a random amount of jitter to the delay. The interval can optionally scale up after each attempt, for exponential backoff.
There is no MaxTime field. To limit the total time spent retrying, set a deadline on the context passed to Tryer.Try.
Example ¶
package main
import (
"context"
"fmt"
"os"
"time"
"github.com/bobg/retry"
)
func main() {
// With the following config,
// tr.Try will try to execute the function up to 5 times.
// It will wait 100ms after the first attempt, plus or minus up to 50ms of jitter;
// 150 (100 × 1.5) after the second, plus or minus up to 50ms;
// 225 (100 × 1.5 × 1.5) after the third, plus or minus up to 50ms;
// etc.
tr := retry.Tryer{
Max: 5,
Delay: 100 * time.Millisecond,
Jitter: 50 * time.Millisecond,
Scale: 0.5,
OnRetry: func(_ context.Context, err error, _ int, delay time.Duration) {
fmt.Fprintf(os.Stderr, "Error, will retry after %s: %s\n", delay, err)
},
}
// This context makes sure tr.Try spends no more than about 1 second doing retries.
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
defer cancel()
// Retry a simple function that fails on its first two tries and succeeds on its third.
err := tr.Try(ctx, func(n int) error {
if n < 2 {
fmt.Printf("Failed on try #%d\n", n)
return fmt.Errorf("failed on try #%d", n)
}
fmt.Printf("Succeeded on try #%d\n", n)
return nil
})
if err != nil {
fmt.Printf("Error: %s\n", err)
}
}
Output: Failed on try #0 Failed on try #1 Succeeded on try #2
func (Tryer) Try ¶
Try runs the provided function one or more times until it succeeds, or the provided context is canceled, or certain other conditions are met - see Tryer.
The number of the current attempt is passed to the function as an argument, starting at 0 for the first attempt.
If f succeeds (i.e., returns nil), Try returns nil. Otherwise it returns one of these error-wrapper types: UnretryableError, MaxTriesError, or ContextError.
type UnretryableError ¶
type UnretryableError struct {
Err error
}
UnretryableError is an error returned by Tryer.Try wrapping the error returned by the function when it is determined to be unretryable.
func (UnretryableError) Error ¶
func (e UnretryableError) Error() string
func (UnretryableError) Unwrap ¶
func (e UnretryableError) Unwrap() error