U
    N8cp                     @   s^   d dl Z d dlZd dlZd dlmZmZmZ e eZ	dd Z
G dd dZG dd dZdS )	    N)bucketstandard
throttlingc                 C   sz   t  }tjd| d}t jd|d}t|}tjt	 d}t
|||||d}| jjd|j | jjd|j |S )	Nr   )Zstarting_max_rate
start_time   )max_rateclock)Zretry_event_adapter)rate_adjustorrate_clockertoken_bucketthrottling_detectorr   zbefore-sendzneeds-retry)r   ZClockr   ZCubicCalculatorcurrent_timeZTokenBucketRateClockerr   ZThrottlingErrorDetectorZRetryEventAdapterClientRateLimitermetaeventsregisteron_sending_requeston_receiving_response)clientr   r	   r   r
   r   Zlimiter r   =/tmp/pip-unpacked-wheel-ozje0y8b/botocore/retries/adaptive.pyregister_retry_handler
   s4     r   c                   @   s(   e Zd ZdZdd Zdd Zdd ZdS )	r   g       @c                 C   s2   || _ || _|| _|| _|| _d| _t | _d S )NF)	_rate_adjustor_rate_clocker_token_bucket_throttling_detector_clock_enabled	threadingLock_lock)selfr	   r
   r   r   r   r   r   r   __init__*   s    zClientRateLimiter.__init__c                 K   s   | j r| j  d S N)r   r   acquire)r"   requestkwargsr   r   r   r   :   s    z$ClientRateLimiter.on_sending_requestc              	   K   s   | j  }| j }| jx | jjf |s8| j|}nB| j	sD|}nt
|| jj}| j||}td||| jj d| _	t
|| j| | j_W 5 Q R X d S )NzfThrottling response received, new send rate: %s measured rate: %s, token bucket capacity available: %sT)r   recordr   r   r!   r   Zis_throttling_errorr   Zsuccess_receivedr   minr   r   Zerror_receivedloggerdebugZavailable_capacity_MAX_RATE_ADJUST_SCALE)r"   r'   measured_rate	timestampZnew_rateZrate_to_user   r   r   r   ?   s4    

   z'ClientRateLimiter.on_receiving_responseN)__name__
__module____qualname__r,   r#   r   r   r   r   r   r   r   &   s   r   c                   @   s<   e Zd ZdZdZdZeefddZdddZed	d
 Z	dS )r   z7Tracks the rate at which a client is sending a request.g?g      ?c                 C   sD   || _ d| _|| _t| j  | _d| j | _d| _	t
 | _d S )Nr   r   )r   _measured_rate
_smoothingmathfloorr   _last_bucket_TIME_BUCKET_RANGE_time_bucket_scale_countr   r    r!   )r"   r   Z	smoothingZtime_bucket_ranger   r   r   r#   d   s    zRateClocker.__init__r   c              
   C   s   | j  | j }t|| j | j }|  j|7  _|| jkr|| jt|| j  }|| j	 | j
d| j	   | _
d| _|| _| j
W  5 Q R  S Q R X d S )Nr   r   )r!   r   r   r4   r5   r8   r9   r6   floatr3   r2   )r"   amounttr   Zcurrent_rater   r   r   r(   r   s    

zRateClocker.recordc                 C   s   | j S r$   )r2   )r"   r   r   r   r-      s    zRateClocker.measured_rateN)r   )
r/   r0   r1   __doc__Z_DEFAULT_SMOOTHINGr7   r#   r(   propertyr-   r   r   r   r   r   ]   s   

r   )loggingr4   r   Zbotocore.retriesr   r   r   	getLoggerr/   r*   r   r   r   r   r   r   r   <module>   s   
7