a e3/@sddlmZddlmZmZddlmZddlmZmZm Z ddl m Z m Z ddl mZddlmZmZeefZdZd Zd Zd d Zd dZGdddeZGdddeZGdddeZdddddefddZdS))iscoroutinefunction)datetime timedelta)wraps)isgeneratorfunctionisasyncgenfunctionisclass)ceilfloor) monotonic)AnyStrIterableclosedopenZ half_opencsfdd}|S)zOBuild a predicate function that checks if an exception is a subtype from a listcs t|SN) issubclass)Z thrown_type_ exc_types2/usr/lib/python3.9/site-packages/circuitbreaker.py matches_typessz(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) rr Exceptionriter isinstance STRING_TYPES ValueError TypeErrorcallable)expected_exceptionZfailure_predicaterrrbuild_failure_predicates     r!c@seZdZdZdZeZdZd2ddZddZ dd Z d d Z d d Z ddZ ddZddZddZddZddZddZddZeddZed d!Zed"d#Zed$d%Zed&d'Zed(d)Zed*d+Zed,d-Zed.d/Zd0d1ZdS)3CircuitBreakerNcCsd|_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__@s      zCircuitBreaker.__init__cCs ||Sr)decorate)r6wrappedrrr__call__kszCircuitBreaker.__call__cCsdSrrr6rrr __enter__nszCircuitBreaker.__enter__cCs,|r |||r ||_|n|dS)NF)r/r&_CircuitBreaker__call_failed_CircuitBreaker__call_succeeded)r6exc_type exc_valueZ _tracebackrrr__exit__qs  zCircuitBreaker.__exit__cCs`|jdur2z |j|_Wnty0|j|_Yn0t|t|sLt|rV||S| |S)z; Applies the circuit breaker to a function N) r2 __qualname__AttributeError__name__CircuitBreakerMonitorregisterrr_decorate_async_decorate_sync)r6functionrrrr<zs     zCircuitBreaker.decoratecs<tfdd}tfdd}tr8|S|S)Ncs<jr$jrj|i|Stjg|Ri|Sr)openedr:CircuitBreakerErrorcallargskwargsrMr6rrwrappers z.CircuitBreaker._decorate_sync..wrapperc?sPjr.jr&j|i|EdHdStjg|Ri|EdHdSr)rNr:rOcall_generatorrQrTrr gen_wrappers z2CircuitBreaker._decorate_sync..gen_wrapper)rr)r6rMrUrWrrTrrLs zCircuitBreaker._decorate_synccs<tfdd}tfdd}tr8|S|S)NcsHjr*jr"j|i|IdHStjg|Ri|IdHSr)rNr:rO call_asyncrQrTrrawrappers z0CircuitBreaker._decorate_async..awrappercspjr>jr6j|i|2z3dHW}|Vq6dStjg|Ri|2z3dHW}|VqV6dSr)rNr:rOcall_async_generator)rRrSelrTrr gen_awrappers $z4CircuitBreaker._decorate_async..gen_awrapper)rr)r6rMrYr\rrTrrKs  zCircuitBreaker._decorate_asynccOs6|||i|WdS1s(0YdS)z Calls the decorated function and applies the circuit breaker rules on success or failure :param func: Decorated function Nrr6funcrRrSrrrrPszCircuitBreaker.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 Nrr6r^rRrSr[rrrrVszCircuitBreaker.call_generatorcs<|$||i|IdHWdS1s.0YdS)z Calls the decorated async function and applies the circuit breaker rules on success or failure :param func: Decorated async function Nrr]rrrrXszCircuitBreaker.call_asynccOsL|4||i|2z3dHW}|Vq6Wdn1s>0YdS)z Calls the decorated async generator function and applies the circuit breaker rules on success or failure :param func: Decorated async generator function Nrr_rrrrZsz#CircuitBreaker.call_async_generatorcCst|_d|_d|_dS)zR Close circuit after successful execution and reset failure count Nr)r3r4r&r'r?rrrZ__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_OPENr4r r5r?rrrZ __call_faileds zCircuitBreaker.__call_failedcCs|jtkr|jdkrtS|jSNr)r4raopen_remainingSTATE_HALF_OPENr?rrrstateszCircuitBreaker.statecCstt|jdS)zq The approximate datetime when the circuit breaker will try to recover :return: datetime )Zseconds)rZutcnowrrcr?rrr 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)r5r+r r r )r6ZremainrrrrcszCircuitBreaker.open_remainingcCs|jSr)r'r?rrr failure_countszCircuitBreaker.failure_countcCs |jtkSr)rer3r?rrrrszCircuitBreaker.closedcCs |jtkSr)rerar?rrrrN szCircuitBreaker.openedcCs|jSrr2r?rrrr9szCircuitBreaker.namecCs|jSr)r&r?rrr last_failureszCircuitBreaker.last_failurecCs|jSr)r1r?rrrr:sz CircuitBreaker.fallback_functioncOs|jSrrhr6rRrSrrr__str__szCircuitBreaker.__str__)NNNNN) rH __module__rFr(r*rr%r0r;r>r@rEr<rLrKrPrVrXrZrBrApropertyrerfrcrgrrNr9rir:rkrrrrr":sR +               r"cs$eZdZfddZddZZS)rOcs tt|j|i|||_dS)zf :param circuit_breaker: :param args: :param kwargs: :return: N)superrOr;_circuit_breaker)r6circuit_breakerrRrS __class__rrr; szCircuitBreakerError.__init__cOs*d|jj|jj|jjt|jj|jjfS)NzMCircuit "%s" OPEN until %s (%d failures, %d sec remaining) (last_failure: %r))ror9rfrgroundrcrirjrrrrk*s zCircuitBreakerError.__str__)rHrlrFr;rk __classcell__rrrqrrOs rOc@seZdZiZeddZeedddZeee dddZ ee e dd d Z eee dd d Z eee dd dZdS)rIcCs||j|j<dSr)circuit_breakersr9)clsrprrrrJ7szCircuitBreakerMonitor.register)returncCstt|dkSrb)lenlistget_openrvrrr all_closed;sz CircuitBreakerMonitor.all_closedcCs |jSr)ruvaluesr{rrr get_circuits?sz"CircuitBreakerMonitor.get_circuits)r9rwcCs |j|Sr)ruget)rvr9rrrrCszCircuitBreakerMonitor.getccs|D]}|jr|VqdSr)r~rNrvcircuitrrrrzGs zCircuitBreakerMonitor.get_openccs|D]}|jr|VqdSr)r~rrrrr get_closedMs z CircuitBreakerMonitor.get_closedN)rHrlrFru classmethodrJboolr|r r"r~r rrzrrrrrrI4s rINcCs*t|r||S||||||dSdS)N)r7r8r r9r:)rr<)r7r8r r9r:rvrrrrTs r) Zasynciorrr functoolsrinspectrrrZmathr r timer typingr r bytesstrrr3rardrr!objectr"rrOrIrrrrrs.    "f