in core/circuitbreaker/circuit_breaker.go [305:363]
func (b *slowRtCircuitBreaker) OnRequestComplete(rt uint64, _ error) {
// add slow and add total
metricStat := b.stat
counter, curErr := metricStat.currentCounter()
if curErr != nil {
logging.Error(curErr, "Fail to get current counter in slowRtCircuitBreaker#OnRequestComplete().",
"rule", b.rule)
return
}
if rt > b.maxAllowedRt {
atomic.AddUint64(&counter.slowCount, 1)
}
atomic.AddUint64(&counter.totalCount, 1)
slowCount := uint64(0)
totalCount := uint64(0)
counters := metricStat.allCounter()
for _, c := range counters {
slowCount += atomic.LoadUint64(&c.slowCount)
totalCount += atomic.LoadUint64(&c.totalCount)
}
slowRatio := float64(slowCount) / float64(totalCount)
// handleStateChange
curStatus := b.CurrentState()
if curStatus == Open {
return
} else if curStatus == HalfOpen {
if rt > b.maxAllowedRt {
// fail to probe
b.fromHalfOpenToOpen(1.0)
} else {
b.addCurProbeNum()
if b.probeNumber == 0 || atomic.LoadUint64(&b.curProbeNumber) >= b.probeNumber {
// succeed to probe
b.fromHalfOpenToClosed()
b.resetMetric()
}
}
return
}
// current state is CLOSED
if totalCount < b.minRequestAmount {
return
}
if slowRatio > b.maxSlowRequestRatio || util.Float64Equals(slowRatio, b.maxSlowRequestRatio) {
curStatus = b.CurrentState()
switch curStatus {
case Closed:
b.fromClosedToOpen(slowRatio)
case HalfOpen:
b.fromHalfOpenToOpen(slowRatio)
default:
}
}
return
}