Package failsafe provides fault tolerance and resilience patterns.
Failsafe-go adds fault tolerance to function execution. Functions can be wrapped with one or more resilience policies, for example:
result, err := failsafe.With(retryPolicy).Get(fn)
When multiple policies are provided, are composed around the fn and will handle its results in reverse order. For example, consider:
failsafe.With(fallback, retryPolicy, circuitBreaker).Get(fn)
This creates the following composition when executing the fn and handling its result:
Fallback(RetryPolicy(CircuitBreaker(fn)))
This section is empty.
ErrExecutionCanceled indicates that an execution was canceled by ExecutionResult.Cancel.
This section is empty.
DelayFunc returns a duration to delay for given the ExecutionAttempt.
type DelayablePolicyBuilder[S any, R any] interface { WithDelay(delay time.Duration) S WithDelayFunc(delayFunc DelayFunc[R]) S }
DelayablePolicyBuilder builds policies that can be delayed between executions.
type Execution[R any] interface { ExecutionAttempt[R] IsCanceled() bool Canceled() <-chan struct{} }
Execution contains information about an execution.
ExecutionAttempt contains information for an execution attempt.
type ExecutionDoneEvent[R any] struct { ExecutionInfo Result R Error error }
ExecutionDoneEvent indicates an execution is done.
type ExecutionEvent[R any] struct { ExecutionAttempt[R] }
ExecutionEvent indicates an execution was attempted.
ExecutionInfo contains execution info.
type ExecutionResult[R any] interface { Done() <-chan any IsDone() bool Get() (R, error) Result() R Error() error Cancel() }
ExecutionResult provides the result of an asynchronous execution.
ExecutionScheduledEvent indicates an execution was scheduled.
type Executor[R any] interface { Compose(innerPolicy Policy[R]) Executor[R] ComposeAny(innerPolicy ResultAgnosticPolicy[any]) Executor[R] Context() context.Context WithContext(ctx context.Context) Executor[R] OnDone(listener func(ExecutionDoneEvent[R])) Executor[R] OnSuccess(listener func(ExecutionDoneEvent[R])) Executor[R] OnFailure(listener func(ExecutionDoneEvent[R])) Executor[R] Run(fn func() error) error RunWithExecution(fn func(exec Execution[R]) error) error Get(fn func() (R, error)) (R, error) GetWithExecution(fn func(exec Execution[R]) (R, error)) (R, error) RunAsync(fn func() error) ExecutionResult[R] RunAsyncWithExecution(fn func(exec Execution[R]) error) ExecutionResult[R] GetAsync(fn func() (R, error)) ExecutionResult[R] GetAsyncWithExecution(fn func(exec Execution[R]) (R, error)) ExecutionResult[R] }
Executor handles failures according to configured policies. See With for details on creating an Executor.
R is the result type. This type is concurrency safe.
With creates and returns a new Executor for result type R that will handle failures according to the given policies. The policies are composed around a func and will handle its results in reverse order. For example, consider:
failsafe.With(fallback, retryPolicy, circuitBreaker).Get(fn)
This creates the following composition when executing a func and handling its result:
Fallback(RetryPolicy(CircuitBreaker(func)))
WithAny creates and returns a new Executor that can be used to compose other policies with the result type R, for the final composed execution. The executor will handle failures according to the given policies.
type FailurePolicyBuilder[S any, R any] interface { HandleErrors(errs ...error) S HandleErrorTypes(errs ...any) S HandleResult(result R) S HandleIf(predicate func(R, error) bool) S OnSuccess(listener func(ExecutionEvent[R])) S OnFailure(listener func(ExecutionEvent[R])) S }
FailurePolicyBuilder builds a Policy that allows configurable conditions to determine whether an execution is a failure.
- By default, any error is considered a failure and will be handled by the policy. You can override this by specifying your own handle conditions. The default error handling condition will only be overridden by another condition that handles errors such as Handle or HandleIf. Specifying a condition that only handles results, such as HandleResult will not replace the default error handling condition.
- If multiple handle conditions are specified, any condition that matches an execution result or error will trigger policy handling.