
    Ѯh                     f    U d dl Z d dlZd dlmZ d ZdZeed<   dZeed<   dZ	eed	<    G d
 d      Z
y)    N)Optionalc                  r    t        j                  dt               t        j                  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     x/home/www/academy-backend.kofcorporation.com/venv/lib/python3.12/site-packages/google/cloud/firestore_v1/rate_limiter.pyr	   r	      s0    
 MM	D
 ##%%r   i  default_initial_tokensi,  default_phase_lengthi@B microseconds_per_secondc                   f    e Zd ZdZedefdedee   defdZd Z	dded	e
d
efdZddZddZddZy)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                 4   d| _         || _        d | _        d | _        || _        | j                  | _        | j                  Jt        | j                  | j                        | _        t        | j
                  | j                        | _        || _        d| _        y )Nr   )	_operations_this_phase_global_max_tokens_start_last_refill_available_tokens_maximum_tokensmin_phase_length_phase)selfr   r   r   s       r   __init__zRateLimiter.__init__G   s     ,-#
 #4379= '5 %)$:$:"".%(&&(?(?&D" $'t';';T=T=T#UD  #/ r   c                     t         j                   j                  t         j                  j                        }| j                  xs || _        | j
                  xs || _        y )N)r   nowtimezoneutcr   r   )r   r	   s     r   _start_clockzRateLimiter._start_clockl   sG    ""&&x'8'8'<'<=kk+V --7r   num
allow_lessreturnc                    | j                          | j                          | j                          |rdn|}| j                  |k\  rBt	        | j                  |      }| xj                  |z  c_        | xj
                  |z  c_        |S y)zCReturns the number of available tokens, up to the amount requested.   r   )r%   _check_phase_refillr   r   r   )r   r&   r'   minimum_tokens_num_to_takes        r   take_tokenszRateLimiter.take_tokensq   sw    (c!!^3t55s;L""l2"''<7'r   c                    | j                   t        d      t        j                  j                  t        j                  j
                        | j                   z
  }|j                  | j                  z  }|| j                  k(  ry| j                  }d| _	        | j                  }|| _        |r!| j                  |kD  r| j                          yyy)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_phases        r   r+   zRateLimiter._check_phase   s     ;;CDD!!("3"3"7"784;;F 	 "kkT-?-?? T[[(%)%@%@&'#"kk$ !T[[>%A))+ &B r   c                     t        | j                  dz        | _        | j                  &t        | j                  | j                        | _        y y )Ng      ?)roundr   r   r   )r   s    r   r3   z$RateLimiter._increase_maximum_tokens   sF    $T%9%9C%?@"".#&t';';T=T=T#UD  /r   c                    | j                   t        d      t        j                  j                  t        j                  j
                        }|| j                   z
  }|r||| _         |j                  dk\  r| j                  | _        y|j                  t        z  }t        || j                  z        }t        | j                  | j                  |z         | _        yy)zUReplenishes any tokens that should have regenerated since the last
        operation.Nz+RateLimiter error: unset _last_refill valuer*   )r   r1   r   r"   r#   r$   r2   r   r   microsecondsr   r9   r   )r   r"   time_since_last_refill_percent_of_max
new_tokenss        r   r,   zRateLimiter._refill   s     $IJJ!)!2!2!6!6x7H7H7L7L!M584;L;L5L! #D &--2)-)=)=& +77:QQ   #($:N:N(N"O
 *-((**Z7*&# "r   )r*   F)r(   N)__name__
__module____qualname____doc__r   r   intr   r    r%   boolr/   r+   r3   r,   r
   r   r   r   r   &   si    D 5+/0	## $C=# 	#J8
s D S  ,DV
r   r   )r   r   typingr   r	   r   rC   __annotations__r   r   r   r
   r   r   <module>rG      sD      
& "  !" c "&  &] ]r   