retry

package
v0.3.0 Latest Latest
Warning

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

Go to latest
Published: Jun 29, 2026 License: MIT Imports: 2 Imported by: 0

README

retry

The retry package provides a small helper for retrying operations that may fail transiently. It is intended for shared infrastructure code that needs context-aware retries with exponential backoff and caller-controlled retry decisions without introducing a larger resilience framework.

Import

import "github.com/raykavin/gobox/retry"

What it provides

  • Do() for retrying an operation up to a fixed number of attempts
  • exponential backoff starting at waitMin and capped at waitMax
  • context-aware waiting between attempts
  • caller-defined retry policy through shouldRetry(attempt, err)

Main function

  • Do(): executes fn, stops on success, cancellation, max attempts, or when shouldRetry returns false

Example

package main

import (
	"context"
	"errors"
	"log"
	"time"

	"github.com/raykavin/gobox/retry"
)

var errTemporary = errors.New("temporary upstream failure")

func main() {
	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
	defer cancel()

	attempts := 0

	err := retry.Do(
		ctx,
		5,
		200*time.Millisecond,
		2*time.Second,
		func(attempt int, err error) bool {
			log.Printf("attempt %d failed: %v", attempt, err)
			return errors.Is(err, errTemporary)
		},
		func() error {
			attempts++
			if attempts < 3 {
				return errTemporary
			}
			return nil
		},
	)
	if err != nil {
		log.Fatal(err)
	}

	log.Printf("operation succeeded after %d attempts", attempts)
}

Notes

  • the attempt passed to shouldRetry is 1-based and refers to the failed attempt that just completed
  • the backoff progression is waitMin, waitMin*2, waitMin*4, and so on, capped at waitMax
  • if ctx is cancelled while waiting between attempts, Do() returns ctx.Err()
  • when the final attempt fails or retries stop early, Do() returns the last error returned by fn
  • Do() does not validate its inputs, so callers should pass maxAttempts >= 1, waitMin <= waitMax, and non-nil shouldRetry and fn

Documentation

Overview

Package retry provides a small helper for retrying operations that may fail transiently, with exponential backoff and context-aware waiting.

Usage

err := retry.Do(
    ctx,
    5,
    200*time.Millisecond,
    2*time.Second,
    func(attempt int, err error) bool {
        return errors.Is(err, ErrTemporary)
    },
    func() error {
        return callExternalService()
    },
)

Do executes fn up to maxAttempts times. On each failure it calls shouldRetry to decide whether to continue, then waits for an exponentially increasing duration between waitMin and waitMax before the next attempt. If ctx is cancelled while waiting, Do returns ctx.Err() immediately.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Do

func Do(
	ctx context.Context,
	maxAttempts int,
	waitMin, waitMax time.Duration,
	shouldRetry func(attempt int, err error) bool,
	fn func() error,
) error

Do executes fn up to maxAttempts times, backing off exponentially between attempts. It stops early if ctx is cancelled or fn returns a nil error. shouldRetry is called with the attempt index (1-based) and the last error to decide whether to retry.

Types

This section is empty.

Jump to

Keyboard shortcuts

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