ó àtÚ_c@sÙdZddlZddlZddlmZmZddlmZmZddlm Z ddlm Z ddl m Z m Z dZejeƒZed „Zd efd „ƒYZd efd „ƒYZdefd„ƒYZdefd„ƒYZde fd„ƒYZde fd„ƒYZde fd„ƒYZde fd„ƒYZde fd„ƒYZdefd„ƒYZdefd„ƒYZd e fd!„ƒYZd"e fd#„ƒYZ d$efd%„ƒYZ!dS(&sCStandard retry behavior. This contains the default standard retry behavior. It provides consistent behavior with other AWS SDKs. The key base classes uses for retries: * ``BaseRetryableChecker`` - Use to check a specific condition that indicates a retry should happen. This can include things like max attempts, HTTP status code checks, error code checks etc. * ``RetryBackoff`` - Use to determine how long we should backoff until we retry a request. This is the class that will implement delay such as exponential backoff. * ``RetryPolicy`` - Main class that determines if a retry should happen. It can combine data from a various BaseRetryableCheckers to make a final call as to whether or not a retry should happen. It then uses a ``BaseRetryBackoff`` to determine how long to delay. * ``RetryHandler`` - The bridge between botocore's event system used by endpoint.py to manage retries and the interfaces defined in this module. This allows us to define an API that has minimal coupling to the event based API used by botocore. iÿÿÿÿN(tConnectionErrortHTTPClientError(tReadTimeoutErrortConnectTimeoutError(tquota(tspecial(tBaseRetryBackofftBaseRetryableCheckericCs´ttjƒƒ}|jjj}|jƒ}|jjjd||j ƒt dt dt d|ƒdt ƒƒdtƒd|ƒ}d|}|jjjd ||jd |ƒ|S( Ns after-call.%st retry_policyt retry_checkert max_attemptst retry_backofftretry_event_adaptert retry_quotasretry-config-%ssneeds-retry.%st unique_id(tRetryQuotaCheckerRt RetryQuotatmetat service_modelt service_idt hyphenizeteventstregistertrelease_retry_quotat RetryHandlert RetryPolicytStandardRetryConditionstExponentialBackofftRetryEventAdaptert needs_retry(tclientR R Rtservice_event_namethandlerR((sD/opt/awscli/lib/python2.7/site-packages/botocore/retries/standard.pytregister_retry_handler's        RcBs eZdZd„Zd„ZRS(s™Bridge between botocore's event system and this module. This class is intended to be hooked to botocore's event system as an event handler. cCs||_||_||_dS(N(t _retry_policyt_retry_event_adaptert _retry_quota(tselfRR R ((sD/opt/awscli/lib/python2.7/site-packages/botocore/retries/standard.pyt__init__Fs  cKs’d}|jj|}|jj|ƒrq|jj|ƒra|jj|ƒ}tj d|ƒq~tj dƒn tj dƒ|jj |ƒ|S(s.Connect as a handler to the needs-retry event.s1Retry needed, retrying request after delay of: %ss;Retry needed but retry quota reached, not retrying request.sNot retrying request.N( tNoneR#tcreate_retry_contextR"t should_retryR$tacquire_retry_quotatcompute_retry_delaytloggertdebugt!adapt_retry_response_from_context(R%tkwargst retry_delaytcontext((sD/opt/awscli/lib/python2.7/site-packages/botocore/retries/standard.pyRKs    (t__name__t __module__t__doc__R&R(((sD/opt/awscli/lib/python2.7/site-packages/botocore/retries/standard.pyR@s RcBs eZdZd„Zd„ZRS(s{Adapter to existing retry interface used in the endpoints layer. This existing interface for determining if a retry needs to happen is event based and used in ``botocore.endpoint``. The interface has grown organically over the years and could use some cleanup. This adapter converts that interface into the interface used by the new retry strategies. cKsv|d}|d kr%d }d }n |\}}td|dd|dd|d|d|dd |d d ƒ}|S( s+Create context based on needs-retry kwargs.tresponsetattempt_numbertattemptstoperation_modelt operationt http_responsetparsed_responsetcaught_exceptiontrequest_contextt request_dictR1N(R't RetryContext(R%R/R5R:R;R1((sD/opt/awscli/lib/python2.7/site-packages/botocore/retries/standard.pyR(js       cCs>|jƒ}|jdk r:|jjdiƒj|ƒndS(s/Modify response back to user back from context.tResponseMetadataN(tget_retry_metadataR;R't setdefaulttupdate(R%R1tmetadata((sD/opt/awscli/lib/python2.7/site-packages/botocore/retries/standard.pyR.ƒs  (R2R3R4R(R.(((sD/opt/awscli/lib/python2.7/site-packages/botocore/retries/standard.pyR`s  R?cBsAeZdZdddddd„Zd„Zd„Zd„ZRS(s‘Normalize a response that we use to check if a retry should occur. This class smoothes over the different types of responses we may get from a service including: * A modeled error response from the service that contains a service code and error message. * A raw HTTP response that doesn't contain service protocol specific error keys. * An exception received while attempting to retrieve a response. This could be a ConnectionError we receive from our HTTP layer which could represent that we weren't able to receive a response from the service. This class guarantees that at least one of the above attributes will be non None. This class is meant to provide a read-only view into the properties associated with a possible retryable response. None of the properties are meant to be modified directly. cCsX||_||_||_||_||_|dkrBi}n||_i|_dS(N(R6R8R;R:R<R'R=t_retry_metadata(R%R6R8R;R:R<R=((sD/opt/awscli/lib/python2.7/site-packages/botocore/retries/standard.pyR&¨s        cCsH|jdkrdS|jjdiƒ}t|tƒs;dS|jdƒS(s‡Check if there was a parsed response with an error code. If we could not find any error codes, ``None`` is returned. NtErrortCode(R;R'tgett isinstancetdict(R%terror((sD/opt/awscli/lib/python2.7/site-packages/botocore/retries/standard.pytget_error_codeÁs cKs|jj|dS(súAdd key/value pairs to the retry metadata. This allows any objects during the retry process to add metadata about any checks/validations that happened. This gets added to the response metadata in the retry handler. N(RERC(R%R/((sD/opt/awscli/lib/python2.7/site-packages/botocore/retries/standard.pytadd_retry_metadataÎs cCs |jjƒS(N(REtcopy(R%((sD/opt/awscli/lib/python2.7/site-packages/botocore/retries/standard.pyRAÙsN(R2R3R4R'R&RLRMRA(((sD/opt/awscli/lib/python2.7/site-packages/botocore/retries/standard.pyR?‘s RcBs#eZd„Zd„Zd„ZRS(cCs||_||_dS(N(t_retry_checkert_retry_backoff(R%R R ((sD/opt/awscli/lib/python2.7/site-packages/botocore/retries/standard.pyR&Þs cCs|jj|ƒS(N(ROt is_retryable(R%R1((sD/opt/awscli/lib/python2.7/site-packages/botocore/retries/standard.pyR)âscCs|jj|ƒS(N(RPt delay_amount(R%R1((sD/opt/awscli/lib/python2.7/site-packages/botocore/retries/standard.pyR+ås(R2R3R&R)R+(((sD/opt/awscli/lib/python2.7/site-packages/botocore/retries/standard.pyRÝs  RcBs/eZdZdZdejd„Zd„ZRS(iicCs"|j|_||_||_dS(N(t_BASEt_baset _max_backofft_random(R%t max_backofftrandom((sD/opt/awscli/lib/python2.7/site-packages/botocore/retries/standard.pyR&îs  cCs(t|jƒ|j|jd|jƒS(sCalculates delay based on exponential backoff. This class implements truncated binary exponential backoff with jitter:: t_i = min(rand(0, 1) * 2 ** attempt, MAX_BACKOFF) where ``i`` is the request attempt (0 based). i(tminRVRTR6RU(R%R1((sD/opt/awscli/lib/python2.7/site-packages/botocore/retries/standard.pyRRós(R2R3RSt _MAX_BACKOFFRXR&RR(((sD/opt/awscli/lib/python2.7/site-packages/botocore/retries/standard.pyRéstMaxAttemptsCheckercBseZd„Zd„ZRS(cCs ||_dS(N(t _max_attempts(R%R ((sD/opt/awscli/lib/python2.7/site-packages/botocore/retries/standard.pyR&scCsB|j|jk}|s>tjd|jƒ|jdtƒn|S(NsMax attempts of %s reached.tMaxAttemptsReached(R6R\R,R-RMtTrue(R%R1tunder_max_attempts((sD/opt/awscli/lib/python2.7/site-packages/botocore/retries/standard.pyRQ s (R2R3R&RQ(((sD/opt/awscli/lib/python2.7/site-packages/botocore/retries/standard.pyR[s tTransientRetryableCheckercBsPeZdddgZddddgZeefZd d d d„Zd„Z RS( tRequestTimeouttRequestTimeoutExceptiontPriorRequestNotCompleteiôiöi÷iøcCsi|dkr|j}n|dkr2|j}n|dkrJ|j}n||_||_||_dS(N(R't_TRANSIENT_ERROR_CODESt_TRANSIENT_STATUS_CODESt_TRANSIENT_EXCEPTION_CLSt_transient_error_codest_transient_status_codest_transient_exception_cls(R%ttransient_error_codesttransient_status_codesttransient_exception_cls((sD/opt/awscli/lib/python2.7/site-packages/botocore/retries/standard.pyR&s        cCsj|jƒ|jkrtS|jdk rD|jj|jkrDtSn|jdk rft|j|j ƒSt S(N( RLRgR^R:R't status_codeRhR<RIRitFalse(R%R1((sD/opt/awscli/lib/python2.7/site-packages/botocore/retries/standard.pyRQ,s    N( R2R3RdReRRRfR'R&RQ(((sD/opt/awscli/lib/python2.7/site-packages/botocore/retries/standard.pyR`s   tThrottledRetryableCheckercBsMeZdddddddddd d d d d gZdd„Zd„ZRS(t ThrottlingtThrottlingExceptiontThrottledExceptiontRequestThrottledExceptiontTooManyRequestsExceptiont&ProvisionedThroughputExceededExceptiontTransactionInProgressExceptiontRequestLimitExceededtBandwidthLimitExceededtLimitExceededExceptiontRequestThrottledtSlowDownRctEC2ThrottledExceptioncCs&|dkr|j}n||_dS(N(R't_THROTTLED_ERROR_CODESt_throttled_error_codes(R%tthrottled_error_codes((sD/opt/awscli/lib/python2.7/site-packages/botocore/retries/standard.pyR&Ms  cCs|jƒ|jkS(N(RLR~(R%R1((sD/opt/awscli/lib/python2.7/site-packages/botocore/retries/standard.pyRQRsN(R2R3R}R'R&RQ(((sD/opt/awscli/lib/python2.7/site-packages/botocore/retries/standard.pyRo9s   tModeledRetryableCheckercBs eZdZd„Zd„ZRS(s0Check if an error has been modeled as retryable.cCstƒ|_dS(N(tModeledRetryErrorDetectort_error_detector(R%((sD/opt/awscli/lib/python2.7/site-packages/botocore/retries/standard.pyR&[scCs2|jƒ}|dkrtS|jj|ƒdk S(N(RLR'RnR‚tdetect_error_type(R%R1t error_code((sD/opt/awscli/lib/python2.7/site-packages/botocore/retries/standard.pyRQ^s  (R2R3R4R&RQ(((sD/opt/awscli/lib/python2.7/site-packages/botocore/retries/standard.pyR€Xs RcBs#eZdZdZdZd„ZRS(s<Checks whether or not an error is a modeled retryable error.tTRANSIENT_ERRORtTHROTTLING_ERRORcCs¹|jƒ}|j}|dks+|j r/dSxƒ|jD]x}|jjdƒdk r9|jjdiƒjdƒp{|j}||kr±|jdjdƒr§|jS|jSq9q9WdS(sCDetect the error type associated with an error code and model. This will either return: * ``self.TRANSIENT_ERROR`` - If the error is a transient error * ``self.THROTTLING_ERROR`` - If the error is a throttling error * ``None`` - If the error is neither type of error. Nt retryableRKtcodet throttling( RLR8R't error_shapesRDRHtnameR†R…(R%R1R„top_modeltshapeterror_code_to_check((sD/opt/awscli/lib/python2.7/site-packages/botocore/retries/standard.pyRƒns    (R2R3R4R…R†Rƒ(((sD/opt/awscli/lib/python2.7/site-packages/botocore/retries/standard.pyRestThrottlingErrorDetectorcBseZd„Zd„ZRS(cCs%tƒ|_tƒ|_||_dS(N(Rt_modeled_error_detectorRot_fixed_error_code_detectorR#(R%R ((sD/opt/awscli/lib/python2.7/site-packages/botocore/retries/standard.pyR&‹s  cKsJ|jj|}|jj|ƒr(tS|jj|ƒ}||jjkS(N(R#R(R‘RQR^RRƒR†(R%R/R1t error_type((sD/opt/awscli/lib/python2.7/site-packages/botocore/retries/standard.pytis_throttling_error‘s (R2R3R&R“(((sD/opt/awscli/lib/python2.7/site-packages/botocore/retries/standard.pyRŠs RcBs#eZdZed„Zd„ZRS(s¡Concrete class that implements the standard retry policy checks. Specifically: not max_attempts and (transient or throttled or modeled_retry) cCsOt|ƒ|_ttƒtƒtƒttjƒtjƒgƒgƒ|_ dS(N( R[t_max_attempts_checkertOrRetryCheckerR`RoR€RtRetryIDPCommunicationErrortRetryDDBChecksumErrort_additional_checkers(R%R ((sD/opt/awscli/lib/python2.7/site-packages/botocore/retries/standard.pyR&¢s cCs"|jj|ƒo!|jj|ƒS(N(R”RQR˜(R%R1((sD/opt/awscli/lib/python2.7/site-packages/botocore/retries/standard.pyRQ°s(R2R3R4tDEFAULT_MAX_ATTEMPTSR&RQ(((sD/opt/awscli/lib/python2.7/site-packages/botocore/retries/standard.pyR™s R•cBseZd„Zd„ZRS(cCs ||_dS(N(t _checkers(R%tcheckers((sD/opt/awscli/lib/python2.7/site-packages/botocore/retries/standard.pyR&¶scst‡fd†|jDƒƒS(Nc3s|]}|jˆƒVqdS(N(RQ(t.0tchecker(R1(sD/opt/awscli/lib/python2.7/site-packages/botocore/retries/standard.pys ºs(tanyRš(R%R1((R1sD/opt/awscli/lib/python2.7/site-packages/botocore/retries/standard.pyRQ¹s(R2R3R&RQ(((sD/opt/awscli/lib/python2.7/site-packages/botocore/retries/standard.pyR•µs RcBsJeZdZdZdZeefZd„Zd„Z d„Z d„Z RS(iii cCs||_d|_dS(N(t_quotaR't_last_amount_acquired(R%R((sD/opt/awscli/lib/python2.7/site-packages/botocore/retries/standard.pyR&És cCsa|j|ƒr|j}n |j}|jj|ƒ}|rM||jds0    1L  & %