circuit

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

Circuit Breaker Package

The circuit package provides a generic implementation of the circuit breaker pattern to protect against cascading failures when external dependencies are unavailable.

Overview

The circuit breaker pattern is a design pattern used in modern software development to detect failures and encapsulate the logic of preventing a failure from constantly recurring during maintenance, temporary external system failure, or unexpected system difficulties.

This implementation provides:

  • Generic support for any function that returns a value and an error
  • Configurable error thresholds, volume thresholds, and sleep windows
  • Support for OpenTelemetry tracing
  • Fluent interface for configuration
  • Thread-safe implementation
  • Support for fallback functions

Usage

Basic Usage
import (
    "context"
    "github.com/abitofhelp/servicelib/circuit"
    "github.com/abitofhelp/servicelib/logging"
    "go.uber.org/zap"
)

// Create a circuit breaker
cfg := circuit.DefaultConfig().
    WithEnabled(true).
    WithErrorThreshold(0.5).
    WithVolumeThreshold(10)

logger := logging.NewContextLogger(zap.NewNop())
options := circuit.DefaultOptions().
    WithName("my-service").
    WithLogger(logger)

cb := circuit.NewCircuitBreaker(cfg, options)

// Execute a function with circuit breaking
result, err := circuit.Execute(ctx, cb, "GetUserProfile", func(ctx context.Context) (UserProfile, error) {
    // Call external service
    return userService.GetProfile(ctx, userID)
})
With Fallback
// Execute a function with circuit breaking and fallback
result, err := circuit.ExecuteWithFallback(
    ctx, 
    cb, 
    "GetUserProfile", 
    func(ctx context.Context) (UserProfile, error) {
        // Call external service
        return userService.GetProfile(ctx, userID)
    },
    func(ctx context.Context, err error) (UserProfile, error) {
        // Fallback function
        return UserProfile{Name: "Default User"}, nil
    },
)

Configuration

The circuit breaker can be configured using the Config struct and the fluent interface:

cfg := circuit.DefaultConfig().
    WithEnabled(true).                  // Enable/disable the circuit breaker
    WithTimeout(5 * time.Second).       // Maximum time allowed for a request
    WithMaxConcurrent(100).             // Maximum number of concurrent requests
    WithErrorThreshold(0.5).            // Percentage of errors that will trip the circuit (0.0-1.0)
    WithVolumeThreshold(10).            // Minimum number of requests before the error threshold is checked
    WithSleepWindow(1 * time.Second)    // Time to wait before allowing a single request through in half-open state

States

The circuit breaker has three states:

  1. Closed: The circuit is closed and requests are allowed through.
  2. Open: The circuit is open and requests are not allowed through. All requests will immediately return an error.
  3. Half-Open: After the sleep window has elapsed, the circuit enters the half-open state, allowing a single request through to test if the dependency is healthy. If the request succeeds, the circuit will close; if it fails, the circuit will open again.

OpenTelemetry Integration

The circuit breaker supports OpenTelemetry tracing:

import (
    "go.opentelemetry.io/otel/trace"
)

// Create a tracer
tracer := otelTracer // Your OpenTelemetry tracer

// Configure the circuit breaker with the tracer
options := circuit.DefaultOptions().
    WithName("my-service").
    WithLogger(logger).
    WithOtelTracer(tracer)

cb := circuit.NewCircuitBreaker(cfg, options)

Thread Safety

The circuit breaker is thread-safe and can be used concurrently from multiple goroutines.

Documentation

Overview

Package circuit provides functionality for circuit breaking on external dependencies.

This package implements the circuit breaker pattern to protect against cascading failures when external dependencies are unavailable.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Execute

func Execute[T any](ctx context.Context, cb *CircuitBreaker, operation string, fn func(ctx context.Context) (T, error)) (T, error)

Execute executes the given function with circuit breaking If the circuit is open, it will return an error immediately If the circuit is closed or half-open, it will execute the function and update the circuit state based on the result

func ExecuteWithFallback

func ExecuteWithFallback[T any](ctx context.Context, cb *CircuitBreaker, operation string, fn func(ctx context.Context) (T, error), fallback func(ctx context.Context, err error) (T, error)) (T, error)

ExecuteWithFallback executes the given function with circuit breaking If the circuit is open or the function fails, it will execute the fallback function

Types

type CircuitBreaker

type CircuitBreaker struct {
	// contains filtered or unexported fields
}

CircuitBreaker implements the circuit breaker pattern

func NewCircuitBreaker

func NewCircuitBreaker(config Config, options Options) *CircuitBreaker

NewCircuitBreaker creates a new circuit breaker

func (*CircuitBreaker) GetState

func (cb *CircuitBreaker) GetState() State

GetState returns the current state of the circuit breaker

func (*CircuitBreaker) Reset

func (cb *CircuitBreaker) Reset()

Reset resets the circuit breaker to its initial state

type Config

type Config struct {
	// Enabled determines if the circuit breaker is enabled
	Enabled bool
	// Timeout is the maximum time allowed for a request
	Timeout time.Duration
	// MaxConcurrent is the maximum number of concurrent requests allowed
	MaxConcurrent int
	// ErrorThreshold is the percentage of errors that will trip the circuit (0.0-1.0)
	ErrorThreshold float64
	// VolumeThreshold is the minimum number of requests before the error threshold is checked
	VolumeThreshold int
	// SleepWindow is the time to wait before allowing a single request through in half-open state
	SleepWindow time.Duration
}

Config contains circuit breaker configuration parameters

func DefaultConfig

func DefaultConfig() Config

DefaultConfig returns a default circuit breaker configuration

func (Config) WithEnabled

func (c Config) WithEnabled(enabled bool) Config

WithEnabled sets whether the circuit breaker is enabled

func (Config) WithErrorThreshold

func (c Config) WithErrorThreshold(errorThreshold float64) Config

WithErrorThreshold sets the percentage of errors that will trip the circuit

func (Config) WithMaxConcurrent

func (c Config) WithMaxConcurrent(maxConcurrent int) Config

WithMaxConcurrent sets the maximum number of concurrent requests allowed

func (Config) WithSleepWindow

func (c Config) WithSleepWindow(sleepWindow time.Duration) Config

WithSleepWindow sets the time to wait before allowing a single request through in half-open state

func (Config) WithTimeout

func (c Config) WithTimeout(timeout time.Duration) Config

WithTimeout sets the maximum time allowed for a request

func (Config) WithVolumeThreshold

func (c Config) WithVolumeThreshold(volumeThreshold int) Config

WithVolumeThreshold sets the minimum number of requests before the error threshold is checked

type Options

type Options struct {
	// Logger is used for logging circuit breaker operations
	Logger *logging.ContextLogger
	// Tracer is used for tracing circuit breaker operations
	Tracer telemetry.Tracer
	// Name is the name of the circuit breaker
	Name string
}

Options contains additional options for the circuit breaker

func DefaultOptions

func DefaultOptions() Options

DefaultOptions returns default options for circuit breaker operations

func (Options) WithLogger

func (o Options) WithLogger(logger *logging.ContextLogger) Options

WithLogger sets the logger for the circuit breaker

func (Options) WithName

func (o Options) WithName(name string) Options

WithName sets the name of the circuit breaker

func (Options) WithOtelTracer

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

WithOtelTracer returns Options with an OpenTelemetry tracer

type State

type State int

State represents the state of the circuit breaker

const (
	// Closed means the circuit is closed and requests are allowed through
	Closed State = iota
	// Open means the circuit is open and requests are not allowed through
	Open
	// HalfOpen means the circuit is allowing a limited number of requests through to test if the dependency is healthy
	HalfOpen
)

func (State) String

func (s State) String() string

String returns a string representation of the circuit breaker state

Jump to

Keyboard shortcuts

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