U
    d	                     @   s2   d Z ddlmZ ddlmZ dZG dd dZdS )z.Token bucket implementation for rate limiting.    )deque)	monotonic)TokenBucketc                   @   sZ   e Zd ZdZdZdZdZdddZdd Zdd	 Z	d
d Z
dddZdddZdd ZdS )r   a  Token Bucket Algorithm.

    See Also:
        https://en.wikipedia.org/wiki/Token_Bucket

        Most of this code was stolen from an entry in the ASPN Python Cookbook:
        https://code.activestate.com/recipes/511490/

    Warning:
        Thread Safety: This implementation is not thread safe.
        Access to a `TokenBucket` instance should occur within the critical
        section of any multithreaded code.
    N   c                 C   s.   t || _|| _t || _t | _t | _d S N)floatcapacity_tokens	fill_rater   	timestampr   contents)selfr
   r    r   6/tmp/pip-unpacked-wheel-hqfrjlvz/kombu/utils/limits.py__init__!   s
    

zTokenBucket.__init__c                 C   s   | j | d S r   )r   append)r   itemr   r   r   add(   s    zTokenBucket.addc                 C   s
   | j  S r   )r   popleftr   r   r   r   pop+   s    zTokenBucket.popc                 C   s   | j   d S r   )r   clearr   r   r   r   clear_pending.   s    zTokenBucket.clear_pendingc                 C   s"   ||   kr|  j|8  _dS dS )a  Check if one or more tokens can be consumed.

        Returns:
            bool: true if the number of tokens can be consumed
                from the bucket.  If they can be consumed, a call will also
                consume the requested number of tokens from the bucket.
                Calls will only consume `tokens` (the number requested)
                or zero tokens -- it will never consume a partial number
                of tokens.
        TF)_get_tokensr	   )r   tokensr   r   r   can_consume1   s    zTokenBucket.can_consumec                 C   s    |   }t||}|| | j S )zoReturn estimated time of token availability.

        Returns:
            float: the time in seconds.
        )r   maxr
   )r   r   r	   r   r   r   expected_timeA   s    
zTokenBucket.expected_timec                 C   sB   | j | jk r<t }| j|| j  }t| j| j | | _ || _| j S r   )r	   r   r   r
   r   min)r   nowdeltar   r   r   r   K   s    zTokenBucket._get_tokens)r   )r   )r   )__name__
__module____qualname____doc__r
   r   r   r   r   r   r   r   r   r   r   r   r   r   r   	   s   



r   N)r$   collectionsr   timer   __all__r   r   r   r   r   <module>   s   