Install gobreaker/v2
masterInstall the gobreaker library using go get:
go get github.com/sony/gobreaker/v2repository·master·Indexed 25 days ago
https://github.com/sony/gobreakerA Go implementation of the Circuit Breaker pattern designed to protect resources and improve resilience by preventing repeated attempts of operations likely to fail. It supports three states (StateClosed, StateHalfOpen, StateOpen), configurable trip logic via a Settings struct, and a DistributedCircuitBreaker for synchronizing state across nodes using a SharedDataStore, with a provided Redis implementation.
Install the gobreaker library using go get:
go get github.com/sony/gobreaker/v2The Settings struct allows you to fine-tune the state machine behavior:
Name: The name of the CircuitBreaker.MaxRequests: Maximum number of requests allowed to pass through when the state is half-open. If 0, only 1 request is allowed.Interval: Cyclic period of the closed state to clear internal Counts. If 0, counts are never cleared during the closed state.BucketPeriod: Duration for each bucket in the rolling window strategy. If ≤ 0, a fixed window strategy is used instead. Interval is automatically adjusted to a multiple of BucketPeriod.Timeout: Period of the open state before transitioning to half-open. If 0, defaults to 60 seconds.ReadyToTrip: Function called with a copy of Counts when a request fails in the closed state. If it returns true, the breaker trips to open. Default: trips after 5 consecutive failures.OnStateChange: Callback triggered whenever the state changes.IsSuccessful: Function to determine if an error counts as a success. If nil, all non-nil errors are failures.IsExcluded: Function to determine if an error should be ignored for metrics (e.g., context cancellations). If true, the request is neither a success nor a failure.This example demonstrates how to wrap an HTTP request using a CircuitBreaker that returns []byte.
var cb *gobreaker.CircuitBreaker[[]byte]
func Get(url string) ([]byte, error) {
body, err := cb.Execute(func() ([]byte, error) {
resp, err := http.Get(url)
if err != nil {
return nil, err
}
defer resp.Body.Close()
return io.ReadAll(resp.Body)
})
if err != nil {
return nil, err
}
return body, nil
}NewCircuitBreaker[T] to create a new instance. The type parameter T specifies the return type of the requests being wrapped. You must provide a Settings struct to configure the behavior.Wrap your request logic in the Execute method. Execute accepts a function func() (T, error).
Execute returns an error immediately.gobreaker catches the panic, treats it as an error for the state machine, and then re-panics.To create a new CircuitBreaker, use the NewCircuitBreaker function and provide a Settings struct. The Settings allow you to define the breaker's behavior, including how it trips, how it handles successes/failures, and how it transitions between states.
Name: The identifier for the breaker.MaxRequests: Maximum requests allowed in StateHalfOpen. If 0, it defaults to 1.Interval: The cyclic period for clearing internal counts in StateClosed. If ≤ 0, counts are not cleared.BucketPeriod: Defines the duration for each bucket in a rolling window. If ≤ 0, a fixed window strategy is used.Timeout: The duration the breaker stays in StateOpen before transitioning to StateHalfOpen. If ≤ 0, defaults to 60s.ReadyToTrip: A function called when a request fails in StateClosed. If it returns true, the breaker trips to StateOpen. Default: trips after 5 consecutive failures.OnStateChange: A callback triggered whenever the state changes.IsSuccessful: A function to determine if an error counts as a success. Default: err == nil is a success.IsExcluded: A function to determine if an error should be ignored entirely (not counted as success or failure). Default: no errors are excluded.The Counts struct tracks the metrics used by the state machine. These counts are cleared upon state changes or at Interval boundaries:
Requests: Total requests.TotalSuccesses: Total successful requests.TotalFailures: Total failed requests.TotalExclusions: Total requests ignored via IsExcluded.ConsecutiveSuccesses: Number of consecutive successes.ConsecutiveFailures: Number of consecutive failures.You can inspect the current status of a CircuitBreaker using the State() and Counts() methods.
State(): Returns the current State (StateClosed, StateHalfOpen, or StateOpen).Counts(): Returns the current internal Counts (successes, failures, etc.).The TwoStepCircuitBreaker[T] provides access to the underlying CircuitBreaker metrics and status through the following methods:
Name() string: Returns the name of the circuit breaker.State() State: Returns the current state (e.g., Closed, Open, HalfOpen).Counts() Counts: Returns the internal counters (successes, failures, etc.).To use a DistributedCircuitBreaker, you must provide an implementation of the SharedDataStore interface. This interface is responsible for managing distributed locks and persisting the circuit breaker's state across multiple instances using a shared backend (e.g., Redis).
type SharedDataStore interface {
Lock(name string) error
Unlock(name string) error
GetData(name string) ([]byte, error)
SetData(name string, data []byte) error
}TwoStepCircuitBreaker[T] allows you to decouple the decision to proceed with a request from the reporting of the request's outcome. Instead of wrapping a function, you call Allow() to check if a request is permitted. If permitted, Allow() returns a done callback function. You must call this done(err) callback after your operation completes, passing the resulting error (or nil if successful), to update the breaker's internal state.name key. This is used by the circuit breaker to persist its internal state across distributed nodes.