gobreaker implements the Circuit Breaker pattern in Go.
go get github.com/sony/gobreaker/v2
The struct CircuitBreaker
is a state machine to prevent sending requests that are likely to fail.
The function NewCircuitBreaker
creates a new CircuitBreaker
.
The type parameter T
specifies the return type of requests.
func NewCircuitBreaker[T any](st Settings) *CircuitBreaker[T]
You can configure CircuitBreaker
by the struct Settings
:
type Settings struct {
Name string
MaxRequests uint32
Interval time.Duration
Timeout time.Duration
ReadyToTrip func(counts Counts) bool
OnStateChange func(name string, from State, to State)
IsSuccessful func(err error) bool
}
-
Name
is the name of theCircuitBreaker
. -
MaxRequests
is the maximum number of requests allowed to pass through when theCircuitBreaker
is half-open. IfMaxRequests
is 0,CircuitBreaker
allows only 1 request. -
Interval
is the cyclic period of the closed state forCircuitBreaker
to clear the internalCounts
, described later in this section. IfInterval
is 0,CircuitBreaker
doesn't clear the internalCounts
during the closed state. -
Timeout
is the period of the open state, after which the state ofCircuitBreaker
becomes half-open. IfTimeout
is 0, the timeout value ofCircuitBreaker
is set to 60 seconds. -
ReadyToTrip
is called with a copy ofCounts
whenever a request fails in the closed state. IfReadyToTrip
returns true,CircuitBreaker
will be placed into the open state. IfReadyToTrip
isnil
, defaultReadyToTrip
is used. DefaultReadyToTrip
returns true when the number of consecutive failures is more than 5. -
OnStateChange
is called whenever the state ofCircuitBreaker
changes. -
IsSuccessful
is called with the error returned from a request. IfIsSuccessful
returns true, the error is counted as a success. Otherwise the error is counted as a failure. IfIsSuccessful
is nil, defaultIsSuccessful
is used, which returns false for all non-nil errors.
The struct Counts
holds the numbers of requests and their successes/failures:
type Counts struct {
Requests uint32
TotalSuccesses uint32
TotalFailures uint32
ConsecutiveSuccesses uint32
ConsecutiveFailures uint32
}
CircuitBreaker
clears the internal Counts
either
on the change of the state or at the closed-state intervals.
Counts
ignores the results of the requests sent before clearing.
CircuitBreaker
can wrap any function to send a request:
func (cb *CircuitBreaker[T]) Execute(req func() (T, error)) (T, error)
The method Execute
runs the given request if CircuitBreaker
accepts it.
Execute
returns an error instantly if CircuitBreaker
rejects the request.
Otherwise, Execute
returns the result of the request.
If a panic occurs in the request, CircuitBreaker
handles it as an error
and causes the same panic again.
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()
body, err := io.ReadAll(resp.Body)
if err != nil {
return nil, err
}
return body, nil
})
if err != nil {
return nil, err
}
return body, nil
}
See example for details.
The MIT License (MIT)
See LICENSE for details.