o
    N,h6                     @   s   d Z ddlZddlZddlmZ ddlmZmZ ddlm	Z	 ddl
mZmZmZmZ e	eZdddddd	ed
ef deeegdf  dededeej deeg ef  dededdfddZdS )a  This module contains a network retry loop implementation.
Its specifically tailored to handling the Telegram API and its errors.

.. versionadded:: 21.11

Hint:
    It was originally part of the `Updater` class, but as part of #4657 it was extracted into its
    own module to be used by other parts of the library.

Warning:
    Contents of this module are intended to be used internally by the library and *not* by the
    user. Changes to this module are not considered breaking changes and may not be documented in
    the changelog.
    N)	Coroutine)CallableOptional)
get_logger)InvalidToken
RetryAfterTelegramErrorTimedOutF)	on_err_cb
stop_event
is_runningrepeat_on_success	action_cb.r
   descriptionintervalr   r   max_retriesr   returnc              
      s  |r|dkrt dd| d|pdd }d fd	d
}	td |}
d}| rzz|	 I dH  |sEtd W W |d7 }dS W n tyi } zd}td|| ||j  }
W Y d}~nld}~w ty } ztd| d}
W Y d}~nRd}~w ty   t	d   t
y } z3|r|| |dk s||k rtd|| n	t	d||  |
dkrdntdd|
 }
W Y d}~nd}~ww |}
W |d7 }n|d7 }w |
rt|
I dH  | s-dS dS )a  Perform a loop calling `action_cb`, retrying after network errors.

    Stop condition for loop in case of ``max_retries < 0``:
        * `is_running()` evaluates :obj:`False`
        * `stop_event` is set.
        * calling `action_cb` succeeds and `repeat_on_success` is :obj:`False`.

    Additional stop condition for loop in case of `max_retries >= 0``:
        * a call to `action_cb` succeeds
        * or `max_retries` is reached.

    Args:
        action_cb (:term:`coroutine function`): Network oriented callback function to call.
        on_err_cb (:obj:`callable`): Optional. Callback to call when TelegramError is caught.
            Receives the exception object as a parameter.

            Hint:
                Only required if you want to handle the error in a special way. Logging about
                the error is already handled by the loop.

            Important:
                Must not raise exceptions! If it does, the loop will be aborted.
        description (:obj:`str`): Description text to use for logs and exception raised.
        interval (:obj:`float` | :obj:`int`): Interval to sleep between each call to
            `action_cb`.
        stop_event (:class:`asyncio.Event` | :obj:`None`): Event to wait on for stopping the
            loop. Setting the event will make the loop exit even if `action_cb` is currently
            running. Defaults to :obj:`None`.
        is_running (:obj:`callable`): Function to check if the loop should continue running.
            Must return a boolean value. Defaults to `lambda: True`.
        max_retries (:obj:`int`): Maximum number of retries before stopping the loop.

            * < 0: Retry indefinitely.
            * 0: No retries.
            * > 0: Number of retries.

        repeat_on_success (:obj:`bool`): Whether to repeat the action after a successful call.
            Defaults to :obj:`False`.

    Raises:
        ValueError: When passing `repeat_on_success=True` and `max_retries >= 0`. This case is
            currently not supported.

    r   z7Cannot use repeat_on_success=True with max_retries >= 0zNetwork Retry Loop (z):c                   S   s   dS )NT r   r   r   k/var/www/www-root/data/www/bot.pdev.uz/venv/lib/python3.10/site-packages/telegram/ext/_utils/networkloop.py<lambda>i   s    z$network_retry_loop.<locals>.<lambda>r   Nc                     s   s  I d H  d S t   } t  }t j| |ft jdI d H \}}tt j |D ]}|  q0W d    n1 sAw   Y  ||v rRt	d d S | 
  d S )N)return_whenz%s Cancelled)asynciocreate_taskwaitFIRST_COMPLETED
contextlibsuppressCancelledErrorcancel_LOGGERdebugresult)action_cb_task	stop_taskdonependingtaskr   
log_prefixr   r   r   	do_actionk   s$   

z%network_retry_loop.<locals>.do_actionz%s Startingz#%s Action succeeded. Stopping loop.   g      ?z/%s %s. Adding %s seconds to the specified time.z'%s Timed out: %s. Retrying immediately.z&%s Invalid token. Aborting retry loop.z(%s Failed run number %s of %s. Retrying.z(%s Failed run number %s of %s. Aborting.   g      ?)r   N)
ValueErrorr   r    r   info_retry_aftertotal_secondsr	   r   	exceptionr   minr   sleep)r   r
   r   r   r   r   r   r   effective_is_runningr)   cur_intervalretriesexc
slack_timetoetelegram_excr   r'   r   network_retry_loop-   sf   7"&r:   )__doc__r   r   collections.abcr   typingr   r   telegram._utils.loggingr   telegram.errorr   r   r   r	   __name__r   strfloatEventboolintr:   r   r   r   r   <module>   s>   
	
