Monday, October 07, 2019

polly simple circuit breaker

- Break (or open) circuit on consecutive 'n' handled exception or handled result for breakDuration interval. Throw brokenCircuitEx when circuit is open.
- When circuit is open and breakDuration has elapsed, the circuitBreaker goes into half-open state. Sample the next call:
    - If it succeeds, close the circuit.
    - If it fails (throws handled ex or handled result), break the circuit again.
- An unhandled ex does not alter the circuit state. An unhandled result closes the circuit.
- The ex or result that breaks the circuit is always thrown or returned. brokenCircuitEx is thrown on the next call.
- When throwing brokenCircuitEx, wrap the last exception or last result that broke the circuit.
// polly circuit breaker
brokenAt = null
count = 0

pollyCircuitBreaker_Execute(
        work, threshold, breakDuration,
        handlesException, handlesResult):
    lock(_lock):
        try:
            if isOpen():
                if lastHandledEx != null:
                    throw brokenCircuitEx(lastHandledEx)
                if lastHandledResult != null:
                    throw brokenCircuitEx(lastHandledResult)
                throw invalidStateEx()
            result = work()
            if handlesResult(result):
                if isHalfOpen():
                    breakCircuit()
                    lastHandledResult = result
                    return result
                if isClosed():
                    count++
                    if thresholdReached():
                        breakCircuit()
                        lastHandledResult = result
                    return result
                throw unsupportedEnumEx()
            // unhandled result
            closeCircuit()
            return result
        catch ex:
            if handlesException(ex):
                if isHalfOpen():
                    breakCircuit()
                    lastHandledEx = ex
                    throw
                if isClosed():
                    count++
                    if thresholdReached():
                        breakCircuit()
                        lastHandledEx = ex
                    throw
                throw unsupportedEnumEx()
            // unhandled ex
            throw

bool thresholdReached():
    return count == threshold
breakCircuit():
    brokenAt = now()
closeCircuit():
    brokenAt = null
    count = 0
    lastHandledEx = null
    lastHandledResult = null

bool isOpen():
    if isClosed():
        return false
    return brokenAt + breakDuration >= now()
bool isHalfOpen():
    if isClosed():
        return false
    return brokenAt + breakDuration < now()
bool isClosed():
    return brokenAt == null

No comments:

Post a Comment