U
    n/e                     @   s6   d Z ddlZddlmZ ddlmZ G dd dZdS )zPAn async reimplementation of the blocking elements from botocore.retries.bucket.    N)CapacityNotAvailableError)Clockc                   @   sv   e Zd ZdZdZefddZedd Zdd Zd	d
 Z	edd Z
edd ZdddZdd Zdd Zdd ZdS )AsyncTokenBucketz5A reimplementation of TokenBucket that doesn't block.g      ?c                 C   s<   d | _ d | _d| _|| _d | _|| _| | t | _	d S )Nr   )

_fill_rate_max_capacity_current_capacity_clock_last_timestamp	_min_rate_set_max_rateasyncio	Condition_new_fill_rate_condition)selfmax_rateZclockZmin_rate r   >/tmp/pip-unpacked-wheel-8mnez3y6/aiobotocore/retries/bucket.py__init__   s    
zAsyncTokenBucket.__init__c                 C   s   | j S N)r   r   r   r   r   r   !   s    zAsyncTokenBucket.max_ratec              
      s8   | j 4 I d H  | | | j   W 5 Q I d H R X d S r   )r   r   notifyr   valuer   r   r   set_max_rate%   s    
zAsyncTokenBucket.set_max_ratec                 C   s@   |    t|| j| _|dkr&|| _nd| _t| j| j| _d S )N   )_refillmaxr
   r   r   minr   r   r   r   r   r   *   s     zAsyncTokenBucket._set_max_ratec                 C   s   | j S r   )r   r   r   r   r   max_capacity<   s    zAsyncTokenBucket.max_capacityc                 C   s   | j S r   )r   r   r   r   r   available_capacity@   s    z#AsyncTokenBucket.available_capacityr   Tc                    sF   | j 4 I dH ( | j||dI dH W  5 Q I dH R  S Q I dH R X dS )aj  Acquire token or return amount of time until next token available.

        If block is True, then this method will return when there's sufficient
        capacity to acquire the desired amount. This won't block the event loop.

        If block is False, then this method will return True if capacity
        was successfully acquired, False otherwise.
        N)amountblock)r   _acquire)r   r    r!   r   r   r   acquireD   s    	zAsyncTokenBucket.acquirec                    s   |    || jkr$|  j|8  _dS |s.t | |}|dkrzt| j |I d H  W n tjk
rr   Y nX |    | |}q8|  j|8  _dS d S )NTr   )	r   r   r   _sleep_amountr   wait_forr   waitTimeoutError)r   r    r!   Zsleep_amountr   r   r   r"   P   s&    

 zAsyncTokenBucket._acquirec                 C   s   || j  | j S r   )r   r   )r   r    r   r   r   r$   f   s    zAsyncTokenBucket._sleep_amountc                 C   sT   | j  }| jd kr|| _d S | j}|| j | j }t| j|| }|| _|| _d S r   )r   current_timer	   r   r   r   r   )r   	timestampZcurrent_capacityZfill_amountZnew_capacityr   r   r   r   i   s    

zAsyncTokenBucket._refillN)r   T)__name__
__module____qualname____doc__Z	_MIN_RATEr   propertyr   r   r   r   r   r#   r"   r$   r   r   r   r   r   r   	   s   	



r   )r-   r   Zbotocore.exceptionsr   Zbotocore.retries.bucketr   r   r   r   r   r   <module>   s   