mirror of
https://github.com/mainflux/mainflux.git
synced 2025-05-12 19:29:30 +08:00
129 lines
3.7 KiB
Markdown
129 lines
3.7 KiB
Markdown
gobreaker
|
|
=========
|
|
|
|
[](http://godoc.org/github.com/sony/gobreaker)
|
|
[](https://travis-ci.org/sony/gobreaker)
|
|
[](https://coveralls.io/github/sony/gobreaker?branch=master)
|
|
|
|
[gobreaker][repo-url] implements the [Circuit Breaker pattern](https://msdn.microsoft.com/en-us/library/dn589784.aspx) in Go.
|
|
|
|
Installation
|
|
------------
|
|
|
|
```
|
|
go get github.com/sony/gobreaker
|
|
```
|
|
|
|
Usage
|
|
-----
|
|
|
|
The struct `CircuitBreaker` is a state machine to prevent sending requests that are likely to fail.
|
|
The function `NewCircuitBreaker` creates a new `CircuitBreaker`.
|
|
|
|
```go
|
|
func NewCircuitBreaker(st Settings) *CircuitBreaker
|
|
```
|
|
|
|
You can configure `CircuitBreaker` by the struct `Settings`:
|
|
|
|
```go
|
|
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)
|
|
}
|
|
```
|
|
|
|
- `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.
|
|
|
|
The struct `Counts` holds the numbers of requests and their successes/failures:
|
|
|
|
```go
|
|
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:
|
|
|
|
```go
|
|
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.
|
|
|
|
Example
|
|
-------
|
|
|
|
```go
|
|
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](https://github.com/sony/gobreaker/blob/master/example) for details.
|
|
|
|
License
|
|
-------
|
|
|
|
The MIT License (MIT)
|
|
|
|
See [LICENSE](https://github.com/sony/gobreaker/blob/master/LICENSE) for details.
|
|
|
|
|
|
[repo-url]: https://github.com/sony/gobreaker
|