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 ¶
- func Execute[T any](ctx context.Context, cb *CircuitBreaker, operation string, ...) (T, error)
- func ExecuteWithFallback[T any](ctx context.Context, cb *CircuitBreaker, operation string, ...) (T, error)
- type CircuitBreaker
- type Config
- func (c Config) WithEnabled(enabled bool) Config
- func (c Config) WithErrorThreshold(errorThreshold float64) Config
- func (c Config) WithMaxConcurrent(maxConcurrent int) Config
- func (c Config) WithSleepWindow(sleepWindow time.Duration) Config
- func (c Config) WithTimeout(timeout time.Duration) Config
- func (c Config) WithVolumeThreshold(volumeThreshold int) Config
- type Options
- type State
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 ¶
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 ¶
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 ¶
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 ¶
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 ¶
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 ¶
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 ¶
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 ¶
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 ¶
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".