From 560478d5cf1fc3a8aab5fe7ec50f9f2537f60c5d Mon Sep 17 00:00:00 2001 From: Edward Date: Fri, 8 May 2020 16:16:04 +0800 Subject: [PATCH] Update readme --- stability/circuit-breaker.md | 74 ++++++++++++++++++------------------ 1 file changed, 37 insertions(+), 37 deletions(-) diff --git a/stability/circuit-breaker.md b/stability/circuit-breaker.md index 66b0487..4631da0 100644 --- a/stability/circuit-breaker.md +++ b/stability/circuit-breaker.md @@ -6,7 +6,7 @@ wires to heat up and combust, the circuit breaker design pattern is a fail-first mechanism that shuts down the circuit, request/response relationship or a service in the case of software development, to prevent bigger failures. -**Note:** The words "circuit" and "service" are used synonymously throught this +**Note:** The words "circuit" and "service" are used synonymously through this document. ## Implementation @@ -24,22 +24,22 @@ failures. package circuit import ( - "time" + "time" ) type State int const ( - UnknownState State = iota - FailureState - SuccessState + UnknownState State = iota + FailureState + SuccessState ) type Counter interface { - Count(State) - ConsecutiveFailures() uint32 - LastActivity() time.Time - Reset() + Count(State) + ConsecutiveFailures() uint32 + LastActivity() time.Time + Reset() } ``` @@ -49,51 +49,51 @@ Circuit is wrapped using the `circuit.Breaker` closure that keeps an internal op It returns a fast error if the circuit has failed consecutively more than the specified threshold. After a while it retries the request and records it. -**Note:** Context type is used here to carry deadlines, cancelation signals, and +**Note:** Context type is used here to carry deadlines, cancellation signals, and other request-scoped values across API boundaries and between processes. ```go package circuit import ( - "context" - "time" + "context" + "time" ) type Circuit func(context.Context) error func Breaker(c Circuit, failureThreshold uint32) Circuit { - cnt := NewCounter() + cnt := NewCounter() - return func(ctx context) error { - if cnt.ConsecutiveFailures() >= failureThreshold { - canRetry := func(cnt Counter) { - backoffLevel := Cnt.ConsecutiveFailures() - failureThreshold + return func(ctx context) error { + if cnt.ConsecutiveFailures() >= failureThreshold { + canRetry := func(cnt Counter) { + backOffLevel := Cnt.ConsecutiveFailures() - failureThreshold - // Calculates when should the circuit breaker resume propagating requests - // to the service - shouldRetryAt := cnt.LastActivity().Add(time.Seconds * 2 << backoffLevel) + // Calculates when should the circuit breaker resume propagating requests + // to the service + shouldRetryAt := cnt.LastActivity().Add(time.Seconds * 2 << backOffLevel) - return time.Now().After(shouldRetryAt) - } + return time.Now().After(shouldRetryAt) + } - if !canRetry(cnt) { - // Fails fast instead of propagating requests to the circuit since - // not enough time has passed since the last failure to retry - return ErrServiceUnavailable - } - } + if !canRetry(cnt) { + // Fails fast instead of propagating requests to the circuit since + // not enough time has passed since the last failure to retry + return ErrServiceUnavailable + } + } - // Unless the failure threshold is exceeded the wrapped service mimics the - // old behavior and the difference in behavior is seen after consecutive failures - if err := c(ctx); err != nil { - cnt.Count(FailureState) - return err - } + // Unless the failure threshold is exceeded the wrapped service mimics the + // old behavior and the difference in behavior is seen after consecutive failures + if err := c(ctx); err != nil { + cnt.Count(FailureState) + return err + } - cnt.Count(SuccessState) - return nil - } + cnt.Count(SuccessState) + return nil + } } ```