retry

package
v1.5.0 Latest Latest
Warning

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

Go to latest
Published: Jun 24, 2025 License: MIT Imports: 9 Imported by: 0

README

Retry Package

The retry package provides functionality for retrying operations with configurable backoff and jitter. It is designed to work seamlessly with the servicelib error framework.

Features

  • Configurable Retry Parameters: Customize maximum retries, initial backoff, maximum backoff, backoff factor, and jitter factor.
  • Exponential Backoff: Automatically increases wait time between retry attempts.
  • Jitter: Adds randomness to backoff times to prevent thundering herd problems.
  • Context Integration: Respects context cancellation and timeouts.
  • Error Framework Integration: Uses the servicelib error framework for consistent error handling.
  • Retryable Error Detection: Provides helper functions to determine if an error is retryable.
  • Structured Logging: Logs retry attempts, backoff times, and errors using the ContextLogger.
  • Distributed Tracing: Optional integration with OpenTelemetry for tracing retry operations.

Usage

See the following examples for how to use the retry package:

  • Basic Usage - A simple example of how to use the retry package with default configuration.
  • Custom Configuration - How to customize retry parameters like max retries, backoff, and jitter.
  • Error Detection - How to use custom error detection to determine if an error is retryable.
  • Logging and Tracing - How to use the retry package with logging and tracing.

Note: The retry.IsNetworkError, retry.IsTimeoutError, and retry.IsTransientError functions are deprecated and will be removed in a future version. Use the corresponding functions from the errors package instead.

Logging and Tracing

The retry package supports structured logging and distributed tracing. You can provide a logger and tracer using the DoWithOptions function.

This will log detailed information about each retry attempt, including:

  • When an attempt starts and finishes
  • The result of each attempt (success or failure)
  • Backoff durations between attempts
  • Error details when attempts fail
  • Final outcome of the retry operation

The logs include trace IDs and span IDs when tracing is enabled, making it easy to correlate logs with traces.

Error Handling

The retry package integrates with the servicelib error framework. It uses the following error types:

  • RetryError: Represents an error that occurred during a retry operation.
  • ContextError: Represents an error that occurred due to a context cancellation or timeout.

These error types can be checked using the following functions from the errors package:

package main

import "github.com/abitofhelp/servicelib/errors"

func checkErrorTypes(err error) {
    // Check if an error is a retry error
    if errors.IsRetryError(err) {
        // Handle retry error
    }

    // Check if an error is a context error
    if errors.IsContextError(err) {
        // Handle context error
    }

    // Check if an error is a timeout error
    if errors.IsTimeout(err) {
        // Handle timeout error
    }
}

Helper Functions

The package provides several helper functions to determine if an error is retryable:

  • IsNetworkError (Deprecated): Returns true if the error is a network-related error. Use errors.IsNetworkError instead.
  • IsTimeoutError (Deprecated): Returns true if the error is a timeout error. Use errors.IsTimeout instead.
  • IsTransientError (Deprecated): Returns true if the error is a transient error. Use errors.IsTransientError instead.

These functions are deprecated and will be removed in a future version. Use the corresponding functions from the errors package instead, as they provide more comprehensive error detection and are maintained as part of the central error handling framework.

Integration with Other Packages

The retry package is designed to work with other servicelib packages. For example, it can be used with the database package to retry database operations:

package main

import (
    "context"
    "database/sql"

    "github.com/abitofhelp/servicelib/db"
    "github.com/abitofhelp/servicelib/retry"
)

func executeWithRetry(ctx context.Context, db *sql.DB) error {
    // Define a function to retry
    fn := func(ctx context.Context) error {
        // Your database operation here
        return nil
    }

    // Use default retry configuration
    config := retry.DefaultConfig()

    // Execute with retry
    return retry.Do(ctx, fn, config, db.IsTransientError)
}

License

This package is part of the servicelib project and is licensed under the same terms.

Documentation

Overview

Package retry provides functionality for retrying operations with configurable backoff and jitter.

This package uses RetryError from the errors/infra package to represent errors that occur during retry operations. This is different from RetryableError in the errors/wrappers package, which is used to wrap errors that should be retried by external systems.

RetryError: Used internally by this package to indicate that all retry attempts have been exhausted. RetryableError: Used by external systems to indicate that an error should be retried.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Do

func Do(ctx context.Context, fn RetryableFunc, config Config, isRetryable IsRetryableError) error

Do executes the given function with retry logic using default options

func DoWithOptions

func DoWithOptions(ctx context.Context, fn RetryableFunc, config Config, isRetryable IsRetryableError, options Options) error

DoWithOptions executes the given function with retry logic and custom options

func IsNetworkError deprecated

func IsNetworkError(err error) bool

Deprecated: Use errors.IsNetworkError instead

func IsTimeoutError deprecated

func IsTimeoutError(err error) bool

Deprecated: Use errors.IsTimeout instead

func IsTransientError deprecated

func IsTransientError(err error) bool

Deprecated: Use errors.IsTransientError instead

Types

type Config

type Config struct {
	MaxRetries      int           // Maximum number of retry attempts
	InitialBackoff  time.Duration // Initial backoff duration
	MaxBackoff      time.Duration // Maximum backoff duration
	BackoffFactor   float64       // Factor by which the backoff increases
	JitterFactor    float64       // Factor for random jitter (0-1)
	RetryableErrors []error       // Errors that are considered retryable
}

Config contains retry configuration parameters

func DefaultConfig

func DefaultConfig() Config

DefaultConfig returns a default retry configuration

func (Config) WithBackoffFactor

func (c Config) WithBackoffFactor(backoffFactor float64) Config

WithBackoffFactor sets the factor by which the backoff increases

func (Config) WithInitialBackoff

func (c Config) WithInitialBackoff(initialBackoff time.Duration) Config

WithInitialBackoff sets the initial backoff duration

func (Config) WithJitterFactor

func (c Config) WithJitterFactor(jitterFactor float64) Config

WithJitterFactor sets the factor for random jitter

func (Config) WithMaxBackoff

func (c Config) WithMaxBackoff(maxBackoff time.Duration) Config

WithMaxBackoff sets the maximum backoff duration

func (Config) WithMaxRetries

func (c Config) WithMaxRetries(maxRetries int) Config

WithMaxRetries sets the maximum number of retry attempts

func (Config) WithRetryableErrors

func (c Config) WithRetryableErrors(retryableErrors []error) Config

WithRetryableErrors sets the errors that are considered retryable

type IsRetryableError

type IsRetryableError func(err error) bool

IsRetryableError is a function that determines if an error is retryable

type Options

type Options struct {
	// Logger is used for logging retry operations
	Logger *logging.ContextLogger
	// Tracer is used for tracing retry operations
	Tracer telemetry.Tracer
}

Options contains additional options for the retry operation

func DefaultOptions

func DefaultOptions() Options

DefaultOptions returns default options for retry operations

func (Options) WithOtelTracer

func (o Options) WithOtelTracer(tracer trace.Tracer) Options

WithOtelTracer returns Options with an OpenTelemetry tracer This allows users to opt-in to OpenTelemetry tracing if they need it

type RetryableFunc

type RetryableFunc func(ctx context.Context) error

RetryableFunc is a function that can be retried

type Span

type Span interface {
	// End completes the span
	End()
	// SetAttributes sets attributes on the span
	SetAttributes(attributes ...attribute.KeyValue)
	// RecordError records an error on the span
	RecordError(err error)
}

Span represents a tracing span

type Tracer

type Tracer interface {
	// Start creates a new span
	Start(ctx context.Context, name string) (context.Context, Span)
}

Tracer is an interface for creating spans

func NewNoopTracer

func NewNoopTracer() Tracer

NewNoopTracer creates a new no-op tracer

func NewOtelTracer

func NewOtelTracer(tracer trace.Tracer) Tracer

NewOtelTracer creates a new OpenTelemetry tracer

Jump to

Keyboard shortcuts

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