o
     i  ã                   @   s\   U d dl Z d dlZd dl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)ÚOptionalc                   C   s   t  dt¡ tj ¡ S )z†
    google.cloud.firestore_v1.rate_limiter.utcnow() is deprecated.
    Use datetime.datetime.now(datetime.timezone.utc) instead.
    zxgoogle.cloud.firestore_v1.rate_limiter.utcnow() is deprecated. Use datetime.datetime.now(datetime.timezone.utc) instead.)ÚwarningsÚwarnÚDeprecationWarningÚdatetimeÚutcnow© r   r   ú†/var/www/snowflake_co_dev_github/snow_flake_back_end_deploy/env/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                   @   sp   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de
defdd„Zddd„Zddd„Zd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__G   s   
ÿ
zRateLimiter.__init__c                 C   s,   t j  t jj¡}| jp|| _| jp|| _d S )N)r   ÚnowÚtimezoneÚutcr   r   )r   r   r   r   r	   Ú_start_clockl   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_tokensq   s   
zRateLimiter.take_tokensc                 C   s|   | j du r	tdƒ‚tj tjj¡| 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.
        Nz%RateLimiter error: unset _start valuer   )r   Ú	TypeErrorr   r   r   r   Úsecondsr   r   r   Ú_increase_maximum_tokens)r   ÚageÚexpected_phaseÚoperations_last_phaseÚprevious_phaser   r   r	   r$   €   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   s€   | j du r	tdƒ‚tj tjj¡}|| j  }|r>|| _ |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.Nz+RateLimiter error: unset _last_refill valuer    )r   r)   r   r   r   r   r*   r   r   Úmicrosecondsr   r0   r   )r   r   Útime_since_last_refillÚ_percent_of_maxÚ
new_tokensr   r   r	   r%   §   s    


ÿ
þïzRateLimiter._refill)r    F)r#   N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r
   r   Úintr   r   r   Úboolr(   r$   r+   r%   r   r   r   r	   r   &   s"    "üþý
ü%

"r   )r   r   Útypingr   r   r
   r9   Ú__annotations__r   r   r   r   r   r   r	   Ú<module>   s   
