retry

package
v0.1.0-preview.4 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 11, 2026 License: Apache-2.0 Imports: 4 Imported by: 0

Documentation

Overview

Package retry provides explicit, bounded, context-aware retry execution.

Index

Examples

Constants

This section is empty.

Variables

View Source
var ErrPanicked = errors.New("retry operation panicked")

ErrPanicked identifies an observed operation panic. Do reports the attempt and re-panics with the original value.

Functions

func Do

func Do[T any](
	ctx context.Context,
	policy Policy,
	operation func(context.Context, Attempt) (T, error),
) (result T, resultErr error)

Do executes an operation until it succeeds, returns a non-retryable error, is canceled, or exhausts the policy.

func Run

func Run(
	ctx context.Context,
	policy Policy,
	operation func(context.Context, Attempt) error,
) error

Run is the error-only form of Do.

Example
package main

import (
	"context"
	"errors"
	"fmt"

	"github.com/spice-framework/spice/retry"
)

func main() {
	transient := errors.New("service unavailable")
	calls := 0
	err := retry.Run(
		context.Background(),
		retry.Policy{
			ID:          "inventory.Refresh",
			Module:      "example.com/shop/inventory",
			MaxAttempts: 3,
			Retryable: func(err error) bool {
				return errors.Is(err, transient)
			},
		},
		func(_ context.Context, _ retry.Attempt) error {
			calls++
			if calls < 3 {
				return transient
			}
			return nil
		},
	)
	fmt.Printf("calls=%d err=%v\n", calls, err)
}
Output:
calls=3 err=<nil>

func Transient

func Transient(err error) bool

Transient retries only errors that explicitly implement TransientError and return true. Cancellation and deadline errors are never retryable.

Types

type Attempt

type Attempt struct {
	Number int
	Max    int
}

Attempt identifies one one-based invocation within a bounded policy.

type ExhaustedError

type ExhaustedError struct {
	Attempts int
	Last     error
}

ExhaustedError reports that every permitted attempt returned a retryable error.

func (*ExhaustedError) Error

func (err *ExhaustedError) Error() string

Error describes the exhausted policy.

func (*ExhaustedError) Unwrap

func (err *ExhaustedError) Unwrap() error

Unwrap exposes the final attempt error.

type Jitter

type Jitter func(Attempt, time.Duration) time.Duration

Jitter explicitly adjusts one computed backoff. It must return a duration between zero and Policy.MaxBackoff.

type Observation

type Observation struct {
	ID          string
	Module      string
	Attempt     Attempt
	Duration    time.Duration
	Err         error
	NextBackoff time.Duration
	Panicked    bool
}

Observation is one completed attempt. NextBackoff is non-zero only when another attempt will be made.

type Observer

type Observer func(context.Context, Observation)

Observer receives completed attempts synchronously on the executing goroutine. It must not panic or block indefinitely.

type Policy

type Policy struct {
	ID             string
	Module         string
	MaxAttempts    int
	InitialBackoff time.Duration
	MaxBackoff     time.Duration
	Multiplier     uint32
	Retryable      Retryable
	Jitter         Jitter
	Wait           Waiter
	Observer       Observer
}

Policy is one immutable retry execution policy. More than one attempt requires an explicit Retryable classifier.

type Retryable

type Retryable func(error) bool

Retryable decides whether an operation error is safe to retry.

type TransientError

type TransientError interface {
	error
	Transient() bool
}

TransientError explicitly marks whether an error is safe to retry. Generated policies use this narrow contract when no application classifier is named.

type Waiter

type Waiter func(context.Context, time.Duration) error

Waiter waits between attempts. A nil Waiter uses a context-aware timer. Explicit waiters support virtual clocks and application-specific scheduling.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL