
    \j                     L    d dl mZ  G d d      Z G d d      Z G d d      Zy)	    )Randomc                   (    e Zd ZdZd Zd Zd Zd Zy)RetryDelayStrategya  Encapsulation of configurable backoff/jitter behavior, used for stream connections.

    - The system can either be in a "good" state or a "bad" state. The initial state is "bad"; the
    caller is responsible for indicating when it transitions to "good". When we ask for a new retry
    delay, that implies the state is now transitioning to "bad".

    - There is a configurable base delay, which can be changed at any time (if the SSE server sends
    us a "retry:" directive).

    - There are optional strategies for applying backoff and jitter to the delay.

    This object is meant to be used from a single thread once it's been created; its methods are
    not safe for concurrent use.
    c                 X    || _         || _        || _        || _        d| _        d | _        y )Nr   )_RetryDelayStrategy__base_delay#_RetryDelayStrategy__reset_interval_RetryDelayStrategy__backoff_RetryDelayStrategy__jitter _RetryDelayStrategy__retry_count_RetryDelayStrategy__good_since)self
base_delayreset_intervalbackoff_strategyjitter_strategys        C/root/env/lib/python3.12/site-packages/ldclient/impl/retry_delay.py__init__zRetryDelayStrategy.__init__   s0    & .)'     c                 ~   | j                   r/| j                  r#|| j                   z
  | j                  k\  rd| _        d| _         | j                  }| j                  r&| j                  j                  || j                        }| xj                  dz  c_        | j                  r| j                  j                  |      }|S )a(  Computes the next retry interval. This also sets the current state to "bad".

        Note that current_time is passed as a parameter instead of computed by this function to
        guarantee predictable behavior in tests.

        :param float current_time: the current time, in seconds
        r   N   )r   r   r   r   r	   apply_backoffr
   apply_jitter)r   current_timedelays      r   next_retry_delayz#RetryDelayStrategy.next_retry_delay   s     !6!6L4K\K\<\`d`u`u<u!"D !!>>NN008J8JKEa==MM..u5Er   c                     || _         y)zMarks the current state as "good" and records the time.

        :param float good_since: the time that the state became "good", in seconds
        N)r   )r   
good_sinces     r   set_good_sincez!RetryDelayStrategy.set_good_since/   s    
 'r   c                      || _         d| _        y)a  Changes the initial retry delay and resets the backoff (if any) so the next retry will use
        that value.

        This is used to implement the optional SSE behavior where the server sends a "retry:" command to
        set the base retry to a specific value. Note that we will still apply a jitter, if jitter is enabled,
        and subsequent retries will still increase exponentially.
        r   N)r   r   )r   r   s     r   set_base_delayz!RetryDelayStrategy.set_base_delay6   s     'r   N)__name__
__module____qualname____doc__r   r   r   r     r   r   r   r      s    !&'	r   r   c                       e Zd ZdZd Zd Zy)DefaultBackoffStrategya  The default implementation of exponential backoff, which doubles the delay each time up to
    the specified maximum.

    If a reset_interval was specified for the RetryDelayStrategy, and the system has been in a "good"
    state for at least that long, the delay is reset back to the base. This avoids perpetually increasing
    delays in a situation where failures are rare).
    c                     || _         y N"_DefaultBackoffStrategy__max_delay)r   	max_delays     r   r   zDefaultBackoffStrategy.__init__I   s
    $r   c                 L    |d|z  z  }|| j                   k  r|S | j                   S )N   r*   )r   r   retry_countds       r   r   z$DefaultBackoffStrategy.apply_backoffL   s/    Q+%&)))q?t/?/??r   N)r!   r"   r#   r$   r   r   r%   r   r   r'   r'   A   s    %@r   r'   c                       e Zd ZdZddZd Zy)DefaultJitterStrategyzbThe default implementation of jitter, which subtracts a pseudo-random amount from each delay.
    Nc                 2    || _         t        |      | _        y)zCreates an instance.

        :param float ratio: a number in the range [0.0, 1.0] representing 0%-100% jitter
        :param int rand_seed: if not None, will use this random seed (for test determinacy)
        N)_DefaultJitterStrategy__ratior   _DefaultJitterStrategy__random)r   ratio	rand_seeds      r   r   zDefaultJitterStrategy.__init__S   s     y)r   c                 \    || j                   j                         | j                  z  |z  z
  S r)   )r5   randomr4   )r   r   s     r   r   z"DefaultJitterStrategy.apply_jitter\   s(    ,,.=EFFr   r)   )r!   r"   r#   r$   r   r   r%   r   r   r2   r2   P   s    *Gr   r2   N)r9   r   r   r'   r2   r%   r   r   <module>r:      s+    : :x@ @G Gr   