a ٓf(@s8ddlmZddlmZddlmZddlmZddlmZddlmZmZddl m Z m Z ddl m Z mZdd lmZmZzdd lmZWneydd lmZYn0z efZWneyeefZYn0d Zd Zd ZddZddZGdddeZ Gddde!Z"GdddeZ#ddddde fddZ$dS))unicode_literals)division)print_function)absolute_import)wraps)datetime timedelta)isgeneratorfunctionisclass)AnyStrIterable)ceilfloor) monotonicclosedopen half_opencsfdd}|S)zOBuild a predicate function that checks if an exception is a subtype from a listcs t|SN) issubclass) thrown_type_ exc_typesr/sparta/input/_build_configuration/image_build+validate/lib/bmcenv/lib64/python3.9/site-packages/circuitbreaker.py matches_types sz(in_exception_list..matches_typesr)rrrrrin_exception_lists rcCsvt|rt|trt|}nVz&t|t|tr8tdt|}Wn.typt |r`t|rhtd|}Yn0|S)az Build a failure predicate_function. The returned function has the signature (Type[Exception], Exception) -> bool. Return value True indicates a failure in the underlying function. :param expected_exception: either an type of Exception, iterable of Exception types, or a predicate function. If an Exception type or iterable of Exception types, the failure predicate will return True when a thrown exception type matches one of the provided types. If a predicate function, it will just be returned as is. :return: callable (Type[Exception], Exception) -> bool z9expected_exception cannot be a string. Did you mean name?z1expected_exception does not look like a predicate) r r Exceptionriter isinstance STRING_TYPES ValueError TypeErrorcallable)expected_exceptionfailure_predicaterrrbuild_failure_predicate&s     r&c@seZdZdZdZeZdZd*ddZddZ dd Z d d Z d d Z ddZ ddZddZddZeddZeddZeddZeddZeddZed d!Zed"d#Zed$d%Zed&d'Zd(d)ZdS)+CircuitBreakerNcCsd|_d|_|p|j|_|p |j|_|sTzt|jd}WntyRt j }Yn0t ||_ |pf|j |_||_t|_t|_dS)a Construct a circuit breaker. :param failure_threshold: break open after this many failures :param recovery_timeout: close after this many seconds :param expected_exception: either an type of Exception, iterable of Exception types, or a predicate function. :param name: name for this circuitbreaker :param fallback_function: called when the circuit is opened :return: Circuitbreaker instance :rtype: Circuitbreaker NrEXPECTED_EXCEPTION) _last_failure_failure_countFAILURE_THRESHOLD_failure_thresholdRECOVERY_TIMEOUT_recovery_timeouttype__dict__KeyErrorr'r*r& is_failureFALLBACK_FUNCTION_fallback_function_name STATE_CLOSED_stater_opened)selffailure_thresholdrecovery_timeoutr$namefallback_functionrrr__init__Ns      zCircuitBreaker.__init__cCs ||Sr)decorate)r;wrappedrrr__call__yszCircuitBreaker.__call__cCsdSrrr;rrr __enter__|szCircuitBreaker.__enter__cCs,|r |||r ||_|n|dS)NF)r4r+_CircuitBreaker__call_failed_CircuitBreaker__call_succeeded)r;exc_type exc_value _tracebackrrr__exit__s  zCircuitBreaker.__exit__csnjdur2z j_Wnty0j_Yn0ttrLjnjt fdd}|S)z; Applies the circuit breaker to a function Ncs:jr$jrj|i|Stg|Ri|Sr)openedr?CircuitBreakerError)argskwargscallfunctionr;rrwrappers z(CircuitBreaker.decorate..wrapper) r7 __qualname__AttributeError__name__CircuitBreakerMonitorregisterr call_generatorrQr)r;rRrSrrPrrAs    zCircuitBreaker.decoratecOs6|||i|WdS1s(0YdS)z Calls the decorated function and applies the circuit breaker rules on success or failure :param func: Decorated function Nr)r;funcrNrOrrrrQszCircuitBreaker.callcosB|*||i|D] }|VqWdn1s40YdS)z Calls the decorated generator function and applies the circuit breaker rules on success or failure :param func: Decorated generator function Nr)r;rZrNrOelrrrrYszCircuitBreaker.call_generatorcCst|_d|_d|_dS)zR Close circuit after successful execution and reset failure count Nr)r8r9r+r,rDrrr__call_succeededszCircuitBreaker.__call_succeededcCs,|jd7_|j|jkr(t|_t|_dS)zO Count failure and open circuit, if threshold has been reached N)r,r. STATE_OPENr9rr:rDrrr __call_faileds zCircuitBreaker.__call_failedcCs|jtkr|jdkrtS|jSNr)r9r^open_remainingSTATE_HALF_OPENrDrrrstateszCircuitBreaker.statecCstt|jdS)zq The approximate datetime when the circuit breaker will try to recover :return: datetime )seconds)rutcnowrrarDrrr open_untilszCircuitBreaker.open_untilcCs*|j|jt}|dkr"t|St|S)zk Number of seconds remaining, the circuit breaker stays in OPEN state :return: int r)r:r0rr r)r;remainrrrraszCircuitBreaker.open_remainingcCs|jSr)r,rDrrr failure_countszCircuitBreaker.failure_countcCs |jtkSr)rcr8rDrrrrszCircuitBreaker.closedcCs |jtkSr)rcr^rDrrrrLszCircuitBreaker.openedcCs|jSrr7rDrrrr>szCircuitBreaker.namecCs|jSr)r+rDrrr last_failureszCircuitBreaker.last_failurecCs|jSr)r6rDrrrr?sz CircuitBreaker.fallback_functioncOs|jSrrir;rNrOrrr__str__szCircuitBreaker.__str__)NNNNN)rV __module__rTr-r/rr*r5r@rCrErKrArQrYrGrFpropertyrcrfrarhrrLr>rjr?rlrrrrr'HsJ +             r'cs$eZdZfddZddZZS)rMcs tt|j|i|||_dS)zf :param circuit_breaker: :param args: :param kwargs: :return: N)superrMr@_circuit_breaker)r;circuit_breakerrNrO __class__rrr@szCircuitBreakerError.__init__cOs*d|jj|jj|jjt|jj|jjfS)NzMCircuit "%s" OPEN until %s (%d failures, %d sec remaining) (last_failure: %r))rpr>rfrhroundrarjrkrrrrls zCircuitBreakerError.__str__)rVrmrTr@rl __classcell__rrrrrrMs rMc@sXeZdZiZeddZeddZeddZeddZed d Z ed d Z d S)rWcCs||j|j<dSr)circuit_breakersr>)clsrqrrrrXszCircuitBreakerMonitor.registercCstt|dkSr`)lenlistget_openrwrrr all_closedsz CircuitBreakerMonitor.all_closedcCs |jSr)rvvaluesr{rrr get_circuitssz"CircuitBreakerMonitor.get_circuitscCs |j|Sr)rvget)rwr>rrrr szCircuitBreakerMonitor.getccs|D]}|jr|VqdSr)r~rLrwcircuitrrrrz%s zCircuitBreakerMonitor.get_openccs|D]}|jr|VqdSr)r~rrrrr get_closed,s z CircuitBreakerMonitor.get_closedN) rVrmrTrv classmethodrXr|r~rrzrrrrrrWs     rWNcCs*t|r||S||||||dSdS)N)r<r=r$r>r?)r#rA)r<r=r$r>r?rwrrrr4s r)% __future__rrrr functoolsrrrinspectr r typingr r mathr rtimer ImportError basestringr NameErrorbytesstrr8r^rbrr&objectr'rrMrWrrrrrs@         "3%