gobreaker implements the Circuit Breaker pattern in Go.
go get github.com/sony/gobreaker
The struct CircuitBreaker
is a state machine to prevent sending requests that are likely to fail.
The function NewCircuitBreaker
creates a new CircuitBreaker
.
func NewCircuitBreaker(st Settings) *CircuitBreaker
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
RecordError func(err error) bool
OnStateChange func(name string, from State, to State)
}
-
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. -
RecordError
is called when a non-nil error is returned by the function, and intends to differentiate errors that should be used for tripping the circuit or not. IfRecordError
returns true,CircuitBreaker
will consider the error should be recorded, so the operation will be marked as unsuccessful IfRecordError
returns false,CircuitBreaker
will consider the error should not be recorded, so the operation will be marked as successful IfRecordError
isnil
, defaultRecordError
is used. DefaultRecordError
considers all errors should be recorded -
OnStateChange
is called whenever the state ofCircuitBreaker
changes.
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) Execute(req func() (interface{}, error)) (interface{}, 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 *breaker.CircuitBreaker
func Get(url string) ([]byte, error) {
body, err := cb.Execute(func() (interface{}, error) {
resp, err := http.Get(url)
if err != nil {
return nil, err
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, err
}
return body, nil
})
if err != nil {
return nil, err
}
return body.([]byte), nil
}
See example for details.
The MIT License (MIT)
See LICENSE for details.