Codebase list golang-gopkg-eapache-go-resiliency.v1 / f2d2554
Fix time processing, more docs Evan Huus 9 years ago
1 changed file(s) with 29 addition(s) and 10 deletion(s). Raw diff Collapse all Expand all
2525 lock sync.RWMutex
2626 state state
2727 errors, successes int
28 lastError time.Time
2829 }
2930
30 // New constructs a new circuit-breaker.
31 // New constructs a new circuit-breaker that starts closed.
32 // From closed, the breaker opens if "errorThreshold" errors are seen
33 // without an error-free period of at least "timeout". From open, the
34 // breaker half-closes after "timeout". From half-open, the breaker closes
35 // after "successThreshold" consecutive successes, or opens on a single error.
3136 func New(errorThreshold, successThreshold int, timeout time.Duration) *Breaker {
3237 return &Breaker{
3338 errorThreshold: errorThreshold,
3843
3944 // Run will either return BreakerOpen immediately if the circuit-breaker is
4045 // already open, or it will run the given function and pass along its return
41 // value.
46 // value. It is safe to call Run concurrently on the same Breaker.
4247 func (b *Breaker) Run(x func() error) error {
4348 b.lock.RLock()
4449 state := b.state
5762 return x()
5863 }()
5964
65 b.processResult(result, panicValue)
66
67 if panicValue != nil {
68 // as close as Go lets us come to a "rethrow" although unfortunately
69 // we lose the original panicing location
70 panic(panicValue)
71 }
72
73 return result
74 }
75
76 func (b *Breaker) processResult(result error, panicValue interface{}) {
6077 b.lock.Lock()
6178 defer b.lock.Unlock()
6279
6885 }
6986 }
7087 } else {
88 if b.errors > 0 {
89 expiry := b.lastError //time.Add mutates, so take a copy
90 expiry.Add(b.timeout)
91 if time.Now().After(expiry) {
92 b.errors = 0
93 }
94 }
95
7196 switch b.state {
7297 case closed:
7398 b.errors++
7499 if b.errors == b.errorThreshold {
75100 b.openBreaker()
101 } else {
102 b.lastError = time.Now()
76103 }
77104 case halfOpen:
78105 b.openBreaker()
79106 }
80107 }
81
82 if panicValue != nil {
83 // as close as Go lets us come to a "rethrow" although unfortunately
84 // we lose the original panicing location
85 panic(panicValue)
86 }
87
88 return result
89108 }
90109
91110 func (b *Breaker) openBreaker() {