circuit

package
v1.8.0 Latest Latest
Warning

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

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

README

Circuit Breaker

Overview

The Circuit Breaker component provides a robust implementation of the Circuit Breaker pattern for handling failures in distributed systems. It helps prevent cascading failures by temporarily disabling operations that are likely to fail.

Features

  • Failure Detection: Automatically detects when operations are failing
  • Automatic Recovery: Automatically recovers after a specified sleep window
  • Configurable Thresholds: Customize error and volume thresholds
  • Concurrent Operation Limiting: Limit the number of concurrent operations
  • Fallback Support: Provide fallback mechanisms for when operations fail

Installation

go get github.com/abitofhelp/servicelib/circuit

Quick Start

See the Basic Usage example for a complete, runnable example of how to use the circuit breaker component.

Configuration

See the Custom Configuration example for a complete, runnable example of how to configure the circuit breaker component.

API Documentation

Core Types

The circuit breaker component provides several core types for implementing the Circuit Breaker pattern.

CircuitBreaker

The main type that implements the Circuit Breaker pattern.

type CircuitBreaker struct {
    // Fields
}
Config

Configuration for the CircuitBreaker.

type Config struct {
    Enabled         bool
    Timeout         time.Duration
    MaxConcurrent   int
    ErrorThreshold  float64
    VolumeThreshold int
    SleepWindow     time.Duration
}
State

Represents the state of the circuit breaker.

type State int
Key Methods

The circuit breaker component provides several key methods for implementing the Circuit Breaker pattern.

Execute

Executes an operation with circuit breaking functionality.

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

Executes an operation with circuit breaking functionality and a fallback mechanism.

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)
GetState

Gets the current state of the circuit breaker.

func (cb *CircuitBreaker) GetState() State
Reset

Resets the circuit breaker to its initial state.

func (cb *CircuitBreaker) Reset()

Examples

For complete, runnable examples, see the following directories in the EXAMPLES directory:

Best Practices

  1. Use Fallbacks: Always provide fallback mechanisms for when operations fail
  2. Configure Thresholds: Configure error and volume thresholds based on your application's needs
  3. Monitor States: Monitor the state of your circuit breakers to detect issues
  4. Use Timeouts: Always set appropriate timeouts for your operations
  5. Handle Errors: Properly handle errors returned by the circuit breaker

Troubleshooting

Common Issues
Circuit Always Open

If the circuit is always open, check that your error threshold and volume threshold are not too low.

Circuit Never Opens

If the circuit never opens despite failures, check that your error threshold and volume threshold are not too high.

  • Errors - Error handling for circuit breaker operations
  • Logging - Logging for circuit breaker events
  • Telemetry - Telemetry for circuit breaker operations

Contributing

Contributions to this component are welcome! Please see the Contributing Guide for more information.

License

This project is licensed under the MIT License - see the LICENSE file for details.

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.

Package circuit provides functionality for implementing the circuit breaker pattern.

The circuit breaker pattern is a design pattern used to detect failures and prevent cascading failures in distributed systems. It works by "breaking the circuit" when a certain threshold of failures is reached, preventing further requests from being made to a failing component until it has had time to recover.

This package implements a configurable circuit breaker with three states:

  • Closed: The circuit is closed and requests are allowed through normally.
  • Open: The circuit is open and requests are immediately rejected without being attempted.
  • HalfOpen: After a configurable sleep window, the circuit transitions to half-open state, allowing a limited number of requests through to test if the dependency is healthy.

Key features:

  • Configurable error threshold and volume threshold for tripping the circuit
  • Automatic recovery with configurable sleep window
  • Support for fallback functions when the circuit is open
  • Integration with OpenTelemetry for tracing
  • Comprehensive logging of circuit state changes

Example usage:

// Create a circuit breaker with default configuration
cb := circuit.NewCircuitBreaker(circuit.DefaultConfig(), circuit.DefaultOptions())

// Execute a function with circuit breaking
result, err := circuit.Execute(ctx, cb, "database_query", func(ctx context.Context) (string, error) {
    return db.Query(ctx, "SELECT * FROM users")
})

// Execute a function with circuit breaking and fallback
result, err := circuit.ExecuteWithFallback(
    ctx,
    cb,
    "api_call",
    func(ctx context.Context) (string, error) {
        return api.Call(ctx, "get_data")
    },
    func(ctx context.Context, err error) (string, error) {
        return "fallback_data", nil
    },
)

The circuit package is designed to be used as a dependency by other packages in the application, providing a consistent circuit breaking interface throughout the codebase.

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.
	// If set to false, the circuit breaker becomes a no-op and all requests are allowed through.
	Enabled bool

	// Timeout is the maximum time allowed for a request.
	// Requests that exceed this timeout are considered failures.
	Timeout time.Duration

	// MaxConcurrent is the maximum number of concurrent requests allowed.
	// This helps prevent resource exhaustion during high load.
	MaxConcurrent int

	// ErrorThreshold is the percentage of errors that will trip the circuit (0.0-1.0).
	// When the error rate exceeds this threshold, the circuit will open.
	// For example, 0.5 means the circuit will open when 50% or more of requests fail.
	ErrorThreshold float64

	// VolumeThreshold is the minimum number of requests before the error threshold is checked.
	// This prevents the circuit from opening due to a small number of failures.
	VolumeThreshold int

	// SleepWindow is the time to wait before allowing a single request through in half-open state.
	// After this duration has elapsed since the circuit opened, a test request will be allowed
	// to determine if the dependency has recovered.
	SleepWindow time.Duration
}

Config contains circuit breaker configuration parameters. It defines the behavior of the circuit breaker, including thresholds for tripping the circuit, timeouts, and recovery behavior.

func DefaultConfig

func DefaultConfig() Config

DefaultConfig returns a default circuit breaker configuration with reasonable values. The default configuration includes:

  • Enabled: true (circuit breaker is enabled)
  • Timeout: 5 seconds (requests that take longer are considered failures)
  • MaxConcurrent: 100 (maximum of 100 concurrent requests)
  • ErrorThreshold: 0.5 (circuit opens when 50% or more of requests fail)
  • VolumeThreshold: 10 (minimum of 10 requests before checking error threshold)
  • SleepWindow: 1 second (wait 1 second before testing if dependency has recovered)

Returns:

  • A Config instance with default values.

func (Config) WithEnabled

func (c Config) WithEnabled(enabled bool) Config

WithEnabled sets whether the circuit breaker is enabled. If enabled is set to false, the circuit breaker becomes a no-op and all requests are allowed through.

Parameters:

  • enabled: A boolean indicating whether the circuit breaker should be enabled.

Returns:

  • A new Config instance with the updated Enabled value.

func (Config) WithErrorThreshold

func (c Config) WithErrorThreshold(errorThreshold float64) Config

WithErrorThreshold sets the percentage of errors that will trip the circuit. When the error rate exceeds this threshold, the circuit will open. The value should be between 0 and 1, where 0 means any error will trip the circuit, and 1 means the circuit will never trip. If a value outside this range is provided, it will be clamped to the valid range.

Parameters:

  • errorThreshold: The error threshold as a decimal between 0 and 1.

Returns:

  • A new Config instance with the updated ErrorThreshold value.

func (Config) WithMaxConcurrent

func (c Config) WithMaxConcurrent(maxConcurrent int) Config

WithMaxConcurrent sets the maximum number of concurrent requests allowed. This helps prevent resource exhaustion during high load. If a non-positive value is provided, it will be set to 1.

Parameters:

  • maxConcurrent: The maximum number of concurrent requests allowed.

Returns:

  • A new Config instance with the updated MaxConcurrent value.

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. After this duration has elapsed since the circuit opened, a test request will be allowed to determine if the dependency has recovered. If the test request succeeds, the circuit will close; if it fails, the circuit will remain open for another sleep window. If a non-positive value is provided, it will be set to 1 millisecond.

Parameters:

  • sleepWindow: The duration to wait before testing if the dependency has recovered.

Returns:

  • A new Config instance with the updated SleepWindow value.

func (Config) WithTimeout

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

WithTimeout sets the maximum time allowed for a request. Requests that exceed this timeout are considered failures. If a non-positive value is provided, it will be set to 1 millisecond.

Parameters:

  • timeout: The maximum duration allowed for a request.

Returns:

  • A new Config instance with the updated Timeout value.

func (Config) WithVolumeThreshold

func (c Config) WithVolumeThreshold(volumeThreshold int) Config

WithVolumeThreshold sets the minimum number of requests before the error threshold is checked. This prevents the circuit from opening due to a small number of failures. If a non-positive value is provided, it will be set to 1.

Parameters:

  • volumeThreshold: The minimum number of requests required before checking the error threshold.

Returns:

  • A new Config instance with the updated VolumeThreshold value.

type Options

type Options struct {
	// Logger is used for logging circuit breaker operations.
	// If nil, a no-op logger will be used.
	Logger *logging.ContextLogger

	// Tracer is used for tracing circuit breaker operations.
	// It provides integration with OpenTelemetry for distributed tracing.
	Tracer telemetry.Tracer

	// Name is the name of the circuit breaker.
	// This is useful for identifying the circuit breaker in logs and traces,
	// especially when multiple circuit breakers are used in the same application.
	Name string
}

Options contains additional options for the circuit breaker. These options are not directly related to the circuit breaker behavior itself, but provide additional functionality like logging, tracing, and identification.

func DefaultOptions

func DefaultOptions() Options

DefaultOptions returns default options for circuit breaker operations. The default options include:

  • No logger (a no-op logger will be used)
  • A no-op tracer (no OpenTelemetry integration)
  • Name: "default"

Returns:

  • An Options instance with default values.

func (Options) WithLogger

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

WithLogger sets the logger for the circuit breaker. The logger is used to log circuit breaker operations, such as state transitions, request successes and failures, and initialization events.

Parameters:

  • logger: A ContextLogger instance for logging circuit breaker operations.

Returns:

  • A new Options instance with the updated Logger value.

func (Options) WithName

func (o Options) WithName(name string) Options

WithName sets the name of the circuit breaker. The name is used to identify the circuit breaker in logs and traces, which is especially useful when multiple circuit breakers are used in the same application to protect different resources or operations.

Parameters:

  • name: A string identifier for the circuit breaker.

Returns:

  • A new Options instance with the updated Name value.

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. The tracer is used to create spans for circuit breaker operations, which can be viewed in a distributed tracing system to understand the behavior and performance of the circuit breaker.

Parameters:

  • tracer: An OpenTelemetry trace.Tracer instance.

Returns:

  • A new Options instance with the provided OpenTelemetry tracer.

type State

type State int

State represents the state of the circuit breaker. It defines the three possible states that a circuit breaker can be in: closed (normal operation), open (failing, rejecting requests), or half-open (testing recovery).

const (
	// Closed indicates that the circuit is closed and requests are allowed through normally.
	// This is the default state and represents normal operation.
	Closed State = iota

	// Open indicates that the circuit is open and requests are immediately rejected.
	// This state is entered when the error threshold is exceeded, preventing further
	// requests to a failing component.
	Open

	// HalfOpen indicates that the circuit is allowing a limited number of requests through
	// to test if the dependency has recovered. This state is entered after the sleep window
	// has elapsed since the circuit was opened.
	HalfOpen
)

func (State) String

func (s State) String() string

String returns a string representation of the circuit breaker state. This method implements the fmt.Stringer interface, allowing State values to be easily formatted in log messages and error reports.

Returns:

  • A human-readable string representing the state: "Closed", "Open", "HalfOpen", or "Unknown".

Jump to

Keyboard shortcuts

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