1313
1414// ConsecCircuitBreaker is window sliding CircuitBreaker with failure threshold.
1515type ConsecCircuitBreaker struct {
16- lastFailureTime time.Time
16+ // time.Time is a compund type, split into second and nano for using atomic.
17+ lastFailureTimeSecond int64
18+ lastFailureTimeNano int32
19+
1720 failures uint64
1821 failureThreshold uint64
1922 window time.Duration
@@ -64,7 +67,8 @@ func (cb *ConsecCircuitBreaker) Call(fn func() error, d time.Duration) error {
6467}
6568
6669func (cb * ConsecCircuitBreaker ) ready () bool {
67- if time .Since (cb .lastFailureTime ) > cb .window {
70+ lastFailureTime := cb .loadLastFailureTime ()
71+ if time .Since (lastFailureTime ) > cb .window {
6872 cb .reset ()
6973 return true
7074 }
@@ -78,7 +82,7 @@ func (cb *ConsecCircuitBreaker) success() {
7882}
7983func (cb * ConsecCircuitBreaker ) fail () {
8084 atomic .AddUint64 (& cb .failures , 1 )
81- cb .lastFailureTime = time .Now ()
85+ cb .updateLastFailureTime ( time .Now () )
8286}
8387
8488func (cb * ConsecCircuitBreaker ) Success () {
@@ -94,5 +98,15 @@ func (cb *ConsecCircuitBreaker) Ready() bool {
9498
9599func (cb * ConsecCircuitBreaker ) reset () {
96100 atomic .StoreUint64 (& cb .failures , 0 )
97- cb .lastFailureTime = time .Now ()
101+ cb .updateLastFailureTime (time .Now ())
102+ }
103+
104+ func (cb * ConsecCircuitBreaker ) updateLastFailureTime (cur time.Time ) {
105+ atomic .StoreInt64 (& cb .lastFailureTimeSecond , cur .Unix ())
106+ atomic .StoreInt32 (& cb .lastFailureTimeNano , int32 (cur .UnixNano ()))
107+ }
108+ func (cb * ConsecCircuitBreaker ) loadLastFailureTime () time.Time {
109+ nano := atomic .LoadInt32 (& cb .lastFailureTimeNano )
110+ second := atomic .LoadInt64 (& cb .lastFailureTimeSecond )
111+ return time .Unix (second , int64 (nano ))
98112}
0 commit comments