Documentation ¶
Overview ¶
Package retry invokes a given function until it succeeds. It sleeps in between attempts based the DelayMethod. It is useful in situations that an action might succeed after a few attempt due to unavailable resources or waiting for a condition to happen.
The default DelayMethod sleeps exactly the same amount of time between attempts. You can use the IncrementalDelay method to increment the delays between attempts. It gives a jitter to the delay to prevent Thundering herd problems. If the delay is 0 in either case, it does not sleep between tries. The IncrementalDelay has a maximum delay of 1 second, but if you need a more flexible delay, you can use the IncrementalDelayMax method and give it a max delay.
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func IncrementalDelay ¶
IncrementalDelay increases the delay between attempts up to a second. It adds a jitter to prevent Thundering herd. If the delay is 0, it always returns 0.
Example ¶
// This setup will delay 20ms + 40ms + 80ms + 160ms, and a jitters at 5 // attempts, until on the 6th attempt that it would succeed. l := &retry.Retry{ Attempts: 6, Delay: 20 * time.Millisecond, Method: retry.IncrementalDelay, } i := 0 err := l.Do(func() error { i++ if i < l.Attempts { return errors.New("ignored error") } return nil }) fmt.Println("Error:", err)
Output: Error: <nil>
func IncrementalDelayMax ¶ added in v2.1.0
IncrementalDelayMax returns a DelayMethod that increases the delay between attempts up to the given max duration. It adds a jitter to prevent Thundering herd. If the delay is 0, it always returns 0.
Example ¶
// This setup will delay 20ms + 40ms + 50ms + 50ms, and a jitters at 5 // attempts, until on the 6th attempt that it would succeed. l := &retry.Retry{ Attempts: 6, Delay: 20 * time.Millisecond, Method: retry.IncrementalDelayMax(50 * time.Millisecond), } i := 0 err := l.Do(func() error { i++ if i < l.Attempts { return errors.New("ignored error") } return nil }) fmt.Println("Error:", err)
Output: Error: <nil>
Types ¶
type DelayMethod ¶
DelayMethod determines how the delay behaves. The current attempt is passed on each iteration, with the delay value of the Retry object.
type Retry ¶
Retry attempts to call a given function until it succeeds, or returns a StopError value for a certain amount of times. It will delay between calls for any errors based on the provided Method. Retry is concurrent safe and the zero value does not do anything.
func (Retry) Do ¶
Do calls fn until it returns nil or a StopError. It delays and retries if the fn returns any errors or panics. The value fo the returned error, or the Err of a StopError, or an error with the panic message will be returned at the last cycle.
Example ¶
l := &retry.Retry{ Attempts: 4, } err := l.Do(func() error { return nil }) fmt.Println("Error:", err)
Output: Error: <nil>
Example (Error) ¶
l := &retry.Retry{ Attempts: 4, Delay: time.Nanosecond, } err := l.Do(func() error { return errors.New("some error") }) fmt.Println("Error:", err)
Output: Error: some error
Example (MultipleFuncs) ¶
l := &retry.Retry{ Attempts: 4, Delay: time.Nanosecond, } err := l.Do(func() error { fmt.Println("Running func 1.") return nil }, func() error { fmt.Println("Running func 2.") return nil }, func() error { fmt.Println("Running func 3.") return nil }) fmt.Println("Error:", err)
Output: Running func 1. Running func 2. Running func 3. Error: <nil>
Example (StandardMethod) ¶
l := &retry.Retry{ Attempts: 4, Delay: time.Nanosecond, } i := 0 err := l.Do(func() error { i++ fmt.Printf("Running iteration %d.\n", i) if i < 3 { return errors.New("ignored error") } return nil }) fmt.Println("Error:", err)
Output: Running iteration 1. Running iteration 2. Running iteration 3. Error: <nil>
Example (Zero) ¶
l := &retry.Retry{} err := l.Do(func() error { fmt.Println("this should not happen") return nil }) fmt.Println("Error:", err)
Output: Error: <nil>
type StopError ¶
type StopError struct {
Err error
}
StopError causes the Do method stop trying and will return the Err. This error then is returned by the Do method.
Example ¶
l := &retry.Retry{ Attempts: 10, } i := 0 err := l.Do(func() error { i++ fmt.Printf("Running iteration %d.\n", i) if i > 2 { return &retry.StopError{} } return errors.New("ignored error") }) fmt.Println("Error:", err)
Output: Running iteration 1. Running iteration 2. Running iteration 3. Error: <nil>
Example (StopErr) ¶
l := &retry.Retry{ Attempts: 10, } i := 0 stopErr := &retry.StopError{ Err: errors.New("this is the returned error"), } err := l.Do(func() error { i++ if i > 2 { return stopErr } return errors.New("ignored error") }) fmt.Println("Error:", err) fmt.Println("Stopped with:", stopErr)
Output: Error: this is the returned error Stopped with: this is the returned error