o
    ;i                     @   sX   d dl mZ d dlmZ d dlmZ ddlmZ dZdZ	G dd	 d	Z
G d
d dZdS )    )	timedelta)Union)api_pb2   )InvalidErrori  i \&c                	   @   sD   e Zd ZdZdddddededed	efd
dZdejfddZ	dS )Retriesa#  Adds a retry policy to a Modal function.

    **Usage**

    ```python
    import modal
    app = modal.App()

    # Basic configuration.
    # This sets a policy of max 4 retries with 1-second delay between failures.
    @app.function(retries=4)
    def f():
        pass


    # Fixed-interval retries with 3-second delay between failures.
    @app.function(
        retries=modal.Retries(
            max_retries=2,
            backoff_coefficient=1.0,
            initial_delay=3.0,
        )
    )
    def g():
        pass


    # Exponential backoff, with retry delay doubling after each failure.
    @app.function(
        retries=modal.Retries(
            max_retries=4,
            backoff_coefficient=2.0,
            initial_delay=1.0,
        )
    )
    def h():
        pass
    ```
    g       @      ?g      N@)backoff_coefficientinitial_delay	max_delaymax_retriesr	   r
   r   c                C   s   |dk rt d| d|dk rt d| d|dkr$t d| d	|d
k r0t d| d|dkr<t d| dd|  krFdksOn t d| d|| _|| _t|d| _t|d| _dS )z}
        Construct a new retries policy, supporting exponential and fixed-interval delays via a backoff coefficient.
        r   zInvalid retries number: z(. Function retries must be non-negative.r   zInvalid max_delay: z&. max_delay must be at least 1 second.<   zInvalid max_delay argument: z. Must be between 1-60 seconds.g        z Invalid initial_delay argument: z. Delay must be positive.z. Must be between 0-60 seconds.g      $@zInvalid backoff_coefficient: zC. Coefficient must be between 1.0 (fixed-interval backoff) and 10.0)secondsN)r   r   r	   r   r
   r   )selfr   r	   r
   r    r   A/home/ubuntu/.local/lib/python3.10/site-packages/modal/retries.py__init__6   s$   
zRetries.__init__returnc                 C   s.   t j| j| j| jtdd | jtdd dS )zCConvert this retries policy to an internal protobuf representation.r   )milliseconds)retriesr	   initial_delay_msmax_delay_ms)r   FunctionRetryPolicyr   r	   r
   r   r   r   r   r   r   	_to_protoc   s   zRetries._to_protoN)
__name__
__module____qualname____doc__intfloatr   r   r   r   r   r   r   r   r      s    /	
-r   c                   @   sR   e Zd ZdZdejfddZdeedf fddZ	e
d	edejdefd
dZdS )RetryManagerz;
    Helper class to apply the specified retry policy.
    retry_policyc                 C   s   || _ d| _d S )Nr   )r"   retry_count)r   r"   r   r   r   r   r   s   
zRetryManager.__init__r   Nc                 C   s0   |  j d7  _ | j | jjkrdS | | j | jS )z
        Returns the delay in milliseconds before the next retry, or None
        if the maximum number of retries has been reached.
        r   N)r#   r"   r   _retry_delay_msr   r   r   r   get_delay_msv   s   zRetryManager.get_delay_msattempt_countc                 C   sF   | dk rt d|  |j|j| d   }|tk rtS |tkr!tS |S )z
        Computes the amount of time to sleep before retrying based on the backend_coefficient and initial_delay_ms args.
        r   zFCannot compute retry delay. attempt_count must be at least 1, but was )
ValueErrorr   r	   MIN_INPUT_RETRY_DELAY_MSMAX_INPUT_RETRY_DELAY_MS)r&   r"   delay_msr   r   r   r$      s   zRetryManager._retry_delay_ms)r   r   r   r   r   r   r   r   r    r%   staticmethodr   r$   r   r   r   r   r!   m   s    r!   N)datetimer   typingr   modal_protor   	exceptionr   r(   r)   r   r!   r   r   r   r   <module>   s   `