diff --git a/resiliency/06_circuit_breaker/breaker_options.go b/resiliency/06_circuit_breaker/breaker_options.go index dad1d2a..f139ad4 100644 --- a/resiliency/06_circuit_breaker/breaker_options.go +++ b/resiliency/06_circuit_breaker/breaker_options.go @@ -3,7 +3,7 @@ package circuit import "time" //BreakConditionWatcher check state -type BreakConditionWatcher func(counts counters) bool +type BreakConditionWatcher func(cnter counters) bool //StateChangedEventHandler set event handle type StateChangedEventHandler func(name string, from State, to State) @@ -60,8 +60,8 @@ func Expiry(expiry time.Time) Option { } } -//OnStateChanged set handle of ChangedHandle -func OnStateChanged(handler StateChangedEventHandler) Option { +//WithStateChanged set handle of ChangedHandle +func WithStateChanged(handler StateChangedEventHandler) Option { return func(opts *Options) { opts.OnStateChanged = handler } diff --git a/resiliency/06_circuit_breaker/circuit_breaker.go b/resiliency/06_circuit_breaker/circuit_breaker.go index 6ef678b..fc4e15d 100644 --- a/resiliency/06_circuit_breaker/circuit_breaker.go +++ b/resiliency/06_circuit_breaker/circuit_breaker.go @@ -3,7 +3,7 @@ * @Author: Edward * @Date: 2020-05-10 22:00:58 * @Last Modified by: Edward - * @Last Modified time: 2020-05-22 16:44:57 + * @Last Modified time: 2020-05-22 17:25:56 */ package circuit @@ -36,15 +36,16 @@ const ( //////////////////////////////// //way 2 对象式断路器 // 高级模式 +// 支持多工作者模式 //////////////////////////////// //RequestBreaker for protection type RequestBreaker struct { options Options mutex sync.Mutex - state OperationState //断路器的当前状态 + state State generation uint64 - counts ICounter + cnter ICounter } //NewRequestBreaker return a breaker @@ -56,7 +57,7 @@ func NewRequestBreaker(opts ...Option) *RequestBreaker { Interval: time.Second * 2, // interval to check status Timeout: time.Second * 60, //default to 60 seconds MaxRequests: 5, - WhenToBreak: func(counts counters) bool { return counts.ConsecutiveFailures > 2 }, + WhenToBreak: func(cnter counters) bool { return cnter.ConsecutiveFailures > 2 }, OnStateChanged: func(name string, fromPre State, toCurrent State) {}, } @@ -67,7 +68,7 @@ func NewRequestBreaker(opts ...Option) *RequestBreaker { return &RequestBreaker{ options: defaultOptions, - counts: &counters{}, + cnter: &counters{}, generation: 0, } } @@ -79,14 +80,18 @@ func NewRequestBreaker(opts ...Option) *RequestBreaker { func (rb *RequestBreaker) Do(work func() (interface{}, error)) (interface{}, error) { //before - fmt.Println("before do : request:", rb.counts.Total()) + fmt.Println("before do : request:", rb.cnter.Total()) //handle status + if rb.state == StateOpen && rb.options.Expiry.Before(time.Now()) { + + } + //do work from requested user result, err := work() - fmt.Println("after do : request:", rb.counts.Total()) + fmt.Println("after do : request:", rb.cnter.Total()) return result, err } diff --git a/resiliency/06_circuit_breaker/circuit_breaker_test.go b/resiliency/06_circuit_breaker/circuit_breaker_test.go index 9d30a55..5e9a596 100644 --- a/resiliency/06_circuit_breaker/circuit_breaker_test.go +++ b/resiliency/06_circuit_breaker/circuit_breaker_test.go @@ -3,7 +3,7 @@ * @Author: Edward * @Date: 2020-05-11 10:55:28 * @Last Modified by: Edward - * @Last Modified time: 2020-05-22 16:37:21 + * @Last Modified time: 2020-05-22 17:21:06 */ package circuit @@ -19,6 +19,16 @@ import ( var breaker *RequestBreaker +var onStateChangeEvent = func(name string, from, to State) { + fmt.Println("name:", name, "from:", from, "to", to) +} + +var whenConditionOccurred = func(cnter counters) bool { + //失败率,可以由用户自己定义 + failureRatio := float64(cnter.TotalFailures) / float64(cnter.Requests) + return cnter.Requests >= 3 && failureRatio >= 0.6 +} + func TestObjectBreaker(t *testing.T) { jobToDo := func() (interface{}, error) { @@ -34,13 +44,7 @@ func TestObjectBreaker(t *testing.T) { return body, nil } - whenCondition := func(counts counters) bool { - //失败率,可以由用户自己定义 - failureRatio := float64(counts.TotalFailures) / float64(counts.Requests) - return counts.Requests >= 3 && failureRatio >= 0.6 - } - - breaker = NewRequestBreaker(Name("HTTP GET"), BreakIf(whenCondition)) + breaker = NewRequestBreaker(Name("HTTP GET"), BreakIf(whenConditionOccurred), WithStateChanged(onStateChangeEvent)) body, err := breaker.Do(jobToDo) if err != nil { diff --git a/resiliency/06_circuit_breaker/circuit_counter.go b/resiliency/06_circuit_breaker/circuit_counter.go index 5708243..f1fa83c 100644 --- a/resiliency/06_circuit_breaker/circuit_counter.go +++ b/resiliency/06_circuit_breaker/circuit_counter.go @@ -3,7 +3,7 @@ * @Author: Edward * @Date: 2020-05-22 12:41:54 * @Last Modified by: Edward - * @Last Modified time: 2020-05-22 16:47:37 + * @Last Modified time: 2020-05-22 17:22:35 */ package circuit @@ -40,7 +40,6 @@ type ICounter interface { type counters struct { Requests uint32 //连续的请求次数 - lastState OperationState lastActivity time.Time TotalFailures uint32 TotalSuccesses uint32 @@ -59,7 +58,6 @@ func (c *counters) LastActivity() time.Time { func (c *counters) Reset() { ct := &counters{} ct.lastActivity = c.lastActivity - ct.lastState = c.lastState c = ct } @@ -74,7 +72,7 @@ func (c *counters) Count(statue OperationState) { } c.Requests++ c.lastActivity = time.Now() //更新活动时间 - c.lastState = statue + // c.lastOpResult = statue //handle status change } diff --git a/resiliency/06_circuit_breaker/circuit_func_closure.go b/resiliency/06_circuit_breaker/circuit_func_closure.go index b0304f8..cb8dcb5 100644 --- a/resiliency/06_circuit_breaker/circuit_func_closure.go +++ b/resiliency/06_circuit_breaker/circuit_func_closure.go @@ -3,7 +3,7 @@ * @Author: Edward * @Date: 2020-05-22 12:42:34 * @Last Modified by: Edward - * @Last Modified time: 2020-05-22 16:48:56 + * @Last Modified time: 2020-05-22 17:21:40 */ package circuit @@ -31,7 +31,7 @@ const ( ) type simpleCounter struct { - lastState OperationState + lastOpResult OperationState lastActivity time.Time ConsecutiveSuccesses uint32 ConsecutiveFailures uint32 @@ -44,21 +44,21 @@ func (c *simpleCounter) LastActivity() time.Time { func (c *simpleCounter) Reset() { ct := &simpleCounter{} ct.lastActivity = c.lastActivity - ct.lastState = UnknownState + ct.lastOpResult = UnknownState c = ct } //Count the failure and success -func (c *simpleCounter) Count(statue OperationState) { +func (c *simpleCounter) Count(lastState OperationState) { - switch statue { + switch lastState { case FailureState: c.ConsecutiveFailures++ case SuccessState: c.ConsecutiveSuccesses++ } c.lastActivity = time.Now() //更新活动时间 - c.lastState = statue + c.lastOpResult = lastState //handle status change }