o ?cl9@s ddlZddlZddlZddlmZddlmZmZmZm Z m Z e e Z deee e giZddZddZd%d d Zd%d d Zd%d dZddZddZddZGdddZGdddZGdddeZGdddeZGdddeZGdd d eZGd!d"d"eZGd#d$d$eZdS)&N)crc32) ChecksumErrorConnectionClosedErrorConnectionErrorEndpointConnectionErrorReadTimeoutErrorZGENERAL_CONNECTION_ERRORcCs<|dkr t}n |dkrtd||||d}|S)a1Calculate time to sleep based on exponential function. The format is:: base * growth_factor ^ (attempts - 1) If ``base`` is set to 'rand' then a random number between 0 and 1 will be used as the base. Base must be greater than 0, otherwise a ValueError will be raised. Zrandrz.The 'base' param must be greater than 0, got: )random ValueError)base growth_factorattemptsZ time_to_sleeprp/private/var/folders/cw/wlscbxl13mj6wd668h7l9g9sllkg5j/T/pip-target-b31awkwq/lib/python/botocore/retryhandler.pydelay_exponential+s rcCstjt||dS)zCreate an exponential delay function based on the attempts. This is used so that you only have to pass it the attempts parameter to calculate the delay. r r ) functoolspartialrrrrr!create_exponential_delay_functionBsrcCs$t||d}t||d}t||dS)N)operation_name)checkeraction) create_checker_from_retry_configcreate_retry_action_from_config RetryHandler)configrrrrrrcreate_retry_handlerNs rcCs0|dd}|ddkrt|d|ddSdS)N __default__delaytypeZ exponentialr r r)r)rrZ delay_configrrrrXs  rc Csg}d}g}d|vr5|ddg}|dd}|D]}||}|t|t|}|dur4||q|durc||durc||d} | D]}|t| |t| |}|durb||qHt|dkrqt|d|dSt|} t| |t|dS)Nrpolicies max_attemptsrr)r!)r!retryable_exceptions) getappend_create_single_checker_extract_retryable_exceptionextendlenMaxAttemptsDecorator MultiCheckertuple) rrcheckersr!r"r keyZcurrent_configZretry_exceptionZoperation_policiesZ multi_checkerrrrres>     rcCs2d|dvrt|ddSd|dvrtSdS)Nresponse applies_when socket_errors)_create_single_response_checkerExceptionRaiser)rrrrr%s   r%cCs\d|vrt|d|dd}|Sd|vrt|dd}|Sd|vr*t|dd}|Std)NZservice_error_codeZhttp_status_code) status_code error_code)r3 crc32body)headerzUnknown retry policy)ServiceErrorCodeCheckerHTTPStatusCodeChecker CRC32Checkerr )r.rrrrr1s r1cCsN|d}d|divrtgSd|vr%g}|dD] }|t|q|SdS)Nr/r5r.r0)r#rr' EXCEPTION_MAP)rr/ exceptionsnamerrrr&s r&c@s eZdZdZddZddZdS)raRetry handler. The retry handler takes two params, ``checker`` object and an ``action`` object. The ``checker`` object must be a callable object and based on a response and an attempt number, determines whether or not sufficient criteria for a retry has been met. If this is the case then the ``action`` object (which also is a callable) determines what needs to happen in the event of a retry. cC||_||_dSN)_checker_action)selfrrrrr__init__ zRetryHandler.__init__cKsr|||d}t|jtr|ddd}|d|i|jd i|r2|j|d}td||Stdd S) zHandler for a retry. Intended to be hooked up to an event handler (hence the **kwargs), this will process retries appropriately. )attempt_numberr.caught_exceptionZ request_dictcontextretriesretries_context)r zRetry needed, action of: %szNo retry needed.Nr) isinstancer?r)r#updater@loggerdebug)rAr r.rEkwargsZchecker_kwargsrHresultrrr__call__s   zRetryHandler.__call__N)__name__ __module__ __qualname____doc__rBrOrrrrrs rc@s(eZdZdZddZddZddZdS) BaseCheckerzBase class for retry checkers. Each class is responsible for checking a single criteria that determines whether or not a retry should not happen. cCs0|dur |||S|dur|||Std)aDetermine if retry criteria matches. Note that either ``response`` is not None and ``caught_exception`` is None or ``response`` is None and ``caught_exception`` is not None. :type attempt_number: int :param attempt_number: The total number of times we've attempted to send the request. :param response: The HTTP response (if one was received). :type caught_exception: Exception :param caught_exception: Any exception that was caught while trying to send the HTTP response. :return: True, if the retry criteria matches (and therefore a retry should occur. False if the criteria does not match. Nz,Both response and caught_exception are None.)_check_response_check_caught_exceptionr )rArDr.rErrrrOs zBaseChecker.__call__cCdSr>rrArDr.rrrrUzBaseChecker._check_responsecCrWr>rrArDrErrrrVrYz#BaseChecker._check_caught_exceptionN)rPrQrRrSrOrUrVrrrrrTs  rTc@s*eZdZdZd ddZddZddZdS) r)aAllow retries up to a maximum number of attempts. This will pass through calls to the decorated retry checker, provided that the number of attempts does not exceed max_attempts. It will also catch any retryable_exceptions passed in. Once max_attempts has been exceeded, then False will be returned or the retryable_exceptions that was previously being caught will be raised. NcCs||_||_||_dSr>)r? _max_attempts_retryable_exceptions)rArr!r"rrrrBs zMaxAttemptsDecorator.__init__cCst|rt|dd|j|d<||||}|r8||jkr6|dur.d|dvr.d|ddd<td|dS|SdS) NmaxrZResponseMetadatarTZMaxAttemptsReachedz0Reached the maximum number of retry attempts: %sF)r]r#r[ _should_retryrKrL)rArDr.rErHZ should_retryrrrrOs*  zMaxAttemptsDecorator.__call__c Csh|jr-||jkr-z||||WS|jy,}ztjd|ddWYd}~dSd}~ww||||S)Nz,retry needed, retryable exception caught: %sT)exc_info)r\r[r?rKrL)rArDr.rEerrrr^0s z"MaxAttemptsDecorator._should_retryr>)rPrQrRrSrBrOr^rrrrr)s   r)c@eZdZddZddZdS)r8cC ||_dSr>) _status_code)rAr3rrrrBD zHTTPStatusCodeChecker.__init__cCs&|dj|jkrtd|jdSdS)Nrz5retry needed: retryable HTTP status code received: %sTF)r3rcrKrLrXrrrrUGsz%HTTPStatusCodeChecker._check_responseNrPrQrRrBrUrrrrr8C r8c@ra)r7cCr=r>)rc _error_code)rAr3r4rrrrBSrCz ServiceErrorCodeChecker.__init__cCsJ|dj|jkr#|ddid}||jkr#td|j|jdSdS)NrrErrorZCodez>retry needed: matching HTTP status and error code seen: %s, %sTF)r3rcr#rgrKrL)rArDr.Zactual_error_coderrrrUWs z'ServiceErrorCodeChecker._check_responseNrerrrrr7R r7c@ra)r*cCrbr>Z _checkers)rAr,rrrrBfrdzMultiChecker.__init__cCs(|jD]}||||}|r|SqdS)NFrj)rArDr.rErZchecker_responserrrrOis zMultiChecker.__call__N)rPrQrRrBrOrrrrr*erfr*c@ra)r9cCrbr>) _header_name)rAr6rrrrBts zCRC32Checker.__init__cCsv|d}|j|j}|durtd|jdSt|djd@}|t|ks9tdt||tdt||ddS)Nrz?crc32 check skipped, the %s header is not in the http response.lz>retry needed: crc32 check failed, expected != actual: %s != %sr)Z checksum_typeZexpected_checksumZactual_checksum) headersr#rkrKrLrcontentintr)rArDr. http_responseZ expected_crcZ actual_crc32rrrrUxs( zCRC32Checker._check_responseNrerrrrr9srir9c@seZdZdZddZdS)r2z`Raise any caught exceptions. This class will raise any non None ``caught_exception``. cCs|r>rrZrrrrVsz'ExceptionRaiser._check_caught_exceptionN)rPrQrRrSrVrrrrr2s r2r>)rloggingr binasciirZbotocore.exceptionsrrrrr getLoggerrPrKr:rrrrrr%r1r&rrTr)r8r7r*r9r2rrrrs:    "  ).?