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 the CircuitBreaker
.
MaxRequests
is the maximum number of requests allowed to pass through
when the CircuitBreaker
is half-open.
If MaxRequests
is 0, CircuitBreaker
allows only 1 request.
Interval
is the cyclic period of the closed state
for CircuitBreaker
to clear the internal Counts
, described later in this section.
If Interval
is 0, CircuitBreaker
doesn't clear the internal Counts
during the closed state.
Timeout
is the period of the open state,
after which the state of CircuitBreaker
becomes half-open.
If Timeout
is 0, the timeout value of CircuitBreaker
is set to 60 seconds.
ReadyToTrip
is called with a copy of Counts
whenever a request fails in the closed state.
If ReadyToTrip
returns true, CircuitBreaker
will be placed into the open state.
If ReadyToTrip
is nil
, default ReadyToTrip
is used.
Default ReadyToTrip
returns true when the number of consecutive failures is more than 5.
OnStateChange
is called whenever the state of CircuitBreaker
changes.
IsSuccessful
is called with the error returned from a request.
If IsSuccessful
returns true, the error is counted as a success.
Otherwise the error is counted as a failure.
If IsSuccessful
is nil, default IsSuccessful
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.