Documentation ¶
Overview ¶
Package circuitbreaker is an in-memory implementation of circuit breaker. The idea is that each local node (server) should maintain it's own knowledge of the service availability, instead of depending on external infrastructure like distributed cache.
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
View Source
var ( ErrBrokenCircuit = errors.New("circuit-breaker: broken") ErrIsolatedCircuit = errors.New("circuit-breaker: isolated") )
Functions ¶
func Ratio ¶
func Ratio[T constraints.Integer](n, total T) float64
Types ¶
type CircuitBreaker ¶
type CircuitBreaker struct { OnStateChanged func(ctx context.Context, from, to Status) // contains filtered or unexported fields }
Example ¶
opt := circuitbreaker.NewOption() opt.BreakDuration = 100 * time.Millisecond opt.SamplingDuration = 1 * time.Second cb := circuitbreaker.New(opt) cb.OnStateChanged = func(ctx context.Context, from, to circuitbreaker.Status) { fmt.Printf("status changed from %s to %s\n", from, to) } key := "key" fmt.Println("initial status:") fmt.Println(cb.Status(ctx, key)) // Opens after failure ratio exceeded. for i := 0; i <= int(opt.FailureThreshold+1); i++ { _ = cb.Do(ctx, key, func() error { return errors.New("foo") }) } // Break duration. time.Sleep(105 * time.Millisecond) // Recover. for i := 0; i <= int(opt.SuccessThreshold+1); i++ { _ = cb.Do(ctx, key, func() error { return nil }) }
Output: initial status: closed <nil> status changed from closed to open status changed from open to half-open status changed from half-open to closed
func New ¶
func New(opt *Option) *CircuitBreaker
type ClosedState ¶
type ClosedState struct { SamplingDuration time.Duration FailureThreshold int FailureRatio float64 Now func() time.Time }
Each state holds an option.
func (*ClosedState) Entry ¶
func (c *ClosedState) Entry() *State
type HalfOpenState ¶
type HalfOpenState struct {
SuccessThreshold int
}
func (*HalfOpenState) Entry ¶
func (h *HalfOpenState) Entry() *State
type InMemory ¶
type InMemory struct {
// contains filtered or unexported fields
}
func NewInMemory ¶
func NewInMemory() *InMemory
type IsolatedState ¶
type IsolatedState struct { }
func NewIsolatedState ¶
func NewIsolatedState() *IsolatedState
func (*IsolatedState) Entry ¶
func (s *IsolatedState) Entry() *State
type Option ¶
type RoundTripper ¶
type RoundTripper struct { KeyFromRequest func(*http.Request) string // contains filtered or unexported fields }
Example ¶
opt := circuitbreaker.NewOption() opt.BreakDuration = 100 * time.Millisecond opt.SamplingDuration = 1 * time.Second cb := circuitbreaker.New(opt) cb.OnStateChanged = func(ctx context.Context, from, to circuitbreaker.Status) { fmt.Printf("status changed from %s to %s\n", from, to) } key := "key" fmt.Println("initial status:") fmt.Println(cb.Status(ctx, key)) ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusInternalServerError) })) defer ts.Close() client := ts.Client() client.Transport = circuitbreaker.NewRoundTripper(client.Transport, cb) re := regexp.MustCompile(`\d{5}`) // Opens after failure ratio exceeded. for i := 0; i < int(opt.FailureThreshold)+1; i++ { _, err := client.Get(ts.URL) if err != nil { // Replace port since it changes dynamically and breaks the test. msg := re.ReplaceAllString(err.Error(), "8080") fmt.Println(msg) continue } }
Output: initial status: closed <nil> Get "http://127.0.0.1:8080": 500 Internal Server Error Get "http://127.0.0.1:8080": 500 Internal Server Error Get "http://127.0.0.1:8080": 500 Internal Server Error Get "http://127.0.0.1:8080": 500 Internal Server Error Get "http://127.0.0.1:8080": 500 Internal Server Error Get "http://127.0.0.1:8080": 500 Internal Server Error Get "http://127.0.0.1:8080": 500 Internal Server Error Get "http://127.0.0.1:8080": 500 Internal Server Error Get "http://127.0.0.1:8080": 500 Internal Server Error Get "http://127.0.0.1:8080": 500 Internal Server Error status changed from closed to open Get "http://127.0.0.1:8080": circuit-breaker: broken
func NewRoundTripper ¶
func NewRoundTripper(t transporter, cb breaker) *RoundTripper
Click to show internal directories.
Click to hide internal directories.