o
    ìË·eG  ã                   @   sX   U d dl Z d dlmZmZ dd„ ZdZeed< dZeed< d	Z	eed
< G dd„ dƒZ
dS )é    N)ÚNoReturnÚOptionalc                   C   s
   t j  ¡ S ©N)ÚdatetimeÚutcnow© r   r   ú]/var/www/ideatree/venv/lib/python3.10/site-packages/google/cloud/firestore_v1/rate_limiter.pyr      s   
r   iô  Údefault_initial_tokensi,  Údefault_phase_lengthi@B Úmicroseconds_per_secondc                   @   sz   e Zd ZdZedefdedee defdd„Zdd	„ Z	ddee de
defdd„Zdd„ Zdefdd„Zdefdd„ZdS )ÚRateLimitera  Implements 5/5/5 ramp-up via Token Bucket algorithm.

    5/5/5 is a ramp up strategy that starts with a budget of 500 operations per
    second. Additionally, every 5 minutes, the maximum budget can increase by
    50%. Thus, at 5:01 into a long bulk-writing process, the maximum budget
    becomes 750 operations per second. At 10:01, the budget becomes 1,125
    operations per second.

    The Token Bucket algorithm uses the metaphor of a bucket, or pile, or really
    any container, if we're being honest, of tokens from which a user is able
    to draw. If there are tokens available, you can do the thing. If there are not,
    you can not do the thing. Additionally, tokens replenish at a fixed rate.

    Usage:

        rate_limiter = RateLimiter()
        tokens = rate_limiter.take_tokens(20)

        if not tokens:
            queue_retry()
        else:
            for _ in range(tokens):
                my_operation()

    Args:
        initial_tokens (Optional[int]): Starting size of the budget. Defaults
            to 500.
        phase_length (Optional[int]): Number of seconds, after which, the size
            of the budget can increase by 50%. Such an increase will happen every
            [phase_length] seconds if operation requests continue consistently.
    NÚinitial_tokensÚglobal_max_tokensÚphase_lengthc                 C   s`   d| _ || _d | _d | _|| _| j| _| jd ur(t| j| jƒ| _t| j| jƒ| _|| _d| _d S )Nr   )	Ú_operations_this_phaseÚ_global_max_tokensÚ_startÚ_last_refillÚ_available_tokensÚ_maximum_tokensÚminÚ_phase_lengthÚ_phase)Úselfr   r   r   r   r   r   Ú__init__=   s   
ÿ
zRateLimiter.__init__c                 C   s    | j ptƒ | _ | jptƒ | _d S r   )r   r   r   ©r   r   r   r   Ú_start_clockb   s   zRateLimiter._start_clocké   FÚnumÚ
allow_lessÚreturnc                 C   s^   |   ¡  |  ¡  |  ¡  |rdn|}| j|kr-t| j|ƒ}|  j|8  _|  j|7  _|S dS )zCReturns the number of available tokens, up to the amount requested.r   r   )r   Ú_check_phaseÚ_refillr   r   r   )r   r   r   Úminimum_tokensÚ_num_to_taker   r   r   Útake_tokensf   s   
zRateLimiter.take_tokensc                 C   s`   t ƒ | j }|j| j }|| jkrdS | j}d| _| j}|| _|r,| j|kr.|  ¡  dS dS dS )ac  Increments or decrements [_phase] depending on traffic.

        Every [_phase_length] seconds, if > 50% of available traffic was used
        during the window, increases [_phase], otherwise, decreases [_phase].

        This is a no-op unless a new [_phase_length] number of seconds since the
        start was crossed since it was last called.
        Nr   )r   r   Úsecondsr   r   r   Ú_increase_maximum_tokens)r   ÚageÚexpected_phaseÚoperations_last_phaseÚprevious_phaser   r   r   r!   u   s   	
ÿzRateLimiter._check_phasec                 C   s2   t | jd ƒ| _| jd urt| j| jƒ| _d S d S )Ng      ø?)Úroundr   r   r   r   r   r   r   r'   “   s   
ÿz$RateLimiter._increase_maximum_tokensc                 C   sd   t ƒ }|| j }|r0|| _|jdkr| j| _dS |jt }t|| j ƒ}t| j| j| ƒ| _dS dS )zUReplenishes any tokens that should have regenerated since the last
        operation.r   N)	r   r   r&   r   r   Úmicrosecondsr   r,   r   )r   ÚnowÚtime_since_last_refillÚ_percent_of_maxÚ
new_tokensr   r   r   r"   ˜   s   

ÿ
þïzRateLimiter._refill)r   F)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r	   r
   Úintr   r   r   Úboolr%   r!   r   r'   r"   r   r   r   r   r      s"    "üþý
ü%r   )r   Útypingr   r   r   r	   r6   Ú__annotations__r
   r   r   r   r   r   r   Ú<module>   s   
