Retry

  1. Usage
  2. Failure Handling
  3. Return Values
  4. Max Attempts
  5. Max Duration
  6. Delays
    1. Jitter
  7. Aborts
  8. Event Listeners

Retry policies are used to retry failed executions a certain number of times, with an optional delay between attempts.

Usage

Creating and using a RetryPolicy is straightforward, for example:

// Retry on ErrConnecting up to 3 times with a 1 second delay between attempts
retryPolicy := retrypolicy.Builder[Connection]().
  HandleErrors(ErrConnecting).
  WithDelay(time.Second).
  WithMaxRetries(3).
  Build()
  
// Get with retries
connection, err := failsafe.Get(Connect, retryPolicy)

Failure Handling

A RetryPolicy can be configured to handle only certain results, errors, or conditions as failures:

builder.
  HandleErrors(ErrConnecting).
  HandleResult(nil)

Return Values

By default, when failures occur and retries have been exceeded, a RetryPolicy will return an ExceededError wrapping the last execution result and error. But it can also be configured to return the last result and error instead:

builder.ReturnLastFailure()

If additional handling or an alternative result is needed, additional policies, such as a fallbacks, can be composed around a RetryPolicy.

Max Attempts

By default, a RetryPolicy will allow a maximum of 3 execution attempts. You can configure a different max number of attempts:

builder.WithMaxAttempts(3)

Or a max number of retries:

builder.WithMaxRetries(2)

You can also disable the default max attempt limit:

builder.WithMaxAttempts(-1)

Max Duration

In addition to max attempts, you can also add a max duration for an execution, after which retries will stop if the max attempts haven’t already been reached.

builder.WithMaxDuration(5*time.Minute)

Delays

By default, a RetryPolicy has no delay between attempts. You can configure a fixed delay:

builder.WithDelay(time.Second)

Or a delay that backs off exponentially:

builder.WithBackoff(time.Second, 30*time.Second)

A random delay for some range:

builder.WithRandomDelay(time.Second, 10*time.Second)

Or a computed delay based on an execution result or error:

builder.WithDelayFunc(ComputeDelay)

Jitter

You can also combine a delay with a random jitter factor:

builder.WithJitterFactor(.1)

Or a time based jitter:

builder.WithJitter(100*time.Second)

To cancel running executions, see the execution cancellation docs or Timeout policy.

Aborts

You can also specify which results, errors, or conditions to abort retries on:

builder.
  AbortOnResult(true)
  AbortOnError(ErrConnecting)
  AbortIf(AbortCondition)

Event Listeners

In addition to the standard policy event listeners, a RetryPolicy can notify you with an ExecutionEvent when a retry is scheduled or is about to be attempted, when an execution fails and the max retries are exceeded, or when retries are aborted. For example:

builder.OnRetry(func(e failsafe.ExecutionEvent[any]) {
  logger.Error("Retrying after error", "error", e.LastError())
})