in core/circuitbreaker/circuit_breaker.go [679:730]
func (b *errorCountCircuitBreaker) OnRequestComplete(_ uint64, err error) {
metricStat := b.stat
counter, curErr := metricStat.currentCounter()
if curErr != nil {
logging.Error(curErr, "Fail to get current counter in errorCountCircuitBreaker#OnRequestComplete().",
"rule", b.rule)
return
}
if err != nil {
atomic.AddUint64(&counter.errorCount, 1)
}
atomic.AddUint64(&counter.totalCount, 1)
errorCount := uint64(0)
totalCount := uint64(0)
counters := metricStat.allCounter()
for _, c := range counters {
errorCount += atomic.LoadUint64(&c.errorCount)
totalCount += atomic.LoadUint64(&c.totalCount)
}
// handleStateChangeWhenThresholdExceeded
curStatus := b.CurrentState()
if curStatus == Open {
return
}
if curStatus == HalfOpen {
if err == nil {
b.addCurProbeNum()
if b.probeNumber == 0 || atomic.LoadUint64(&b.curProbeNumber) >= b.probeNumber {
b.fromHalfOpenToClosed()
b.resetMetric()
}
} else {
b.fromHalfOpenToOpen(1)
}
return
}
// current state is CLOSED
if totalCount < b.minRequestAmount {
return
}
if errorCount >= b.errorCountThreshold {
curStatus = b.CurrentState()
switch curStatus {
case Closed:
b.fromClosedToOpen(errorCount)
case HalfOpen:
b.fromHalfOpenToOpen(errorCount)
default:
}
}
}