o
    "hU                     @   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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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TimedOut)	on_err_cb
stop_event
is_running	action_cb.r
   descriptionintervalr   r   max_retriesreturnc              
      s  d| d|pdd }dt f fdd}td |}	d	}
| rzz| I d
H s5W W |
d7 }
d
S W n tyY } zd}td|| ||j  }	W Y d
}~nld
}~w tys } 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 )aD  Perform a loop calling `action_cb`, retrying after network errors.

    Stop condition for loop:
        * `is_running()` evaluates :obj:`False` or
        * return value of `action_cb` evaluates :obj:`False`
        * or `stop_event` is set.
        * 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.

    zNetwork Retry Loop (z):c                   S   s   dS )NT r   r   r   R/var/www/html/venv/lib/python3.10/site-packages/telegram/ext/_utils/networkloop.py<lambda>Y   s    z$network_retry_loop.<locals>.<lambda>r   c                     s   s	  I d H S t   } t  }t j| |ft jdI d H \}}tt j |D ]}|  q.W d    n1 s?w   Y  ||v rPt	d dS | 
 S )N)return_whenz%s CancelledF)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_action[   s"   

z%network_retry_loop.<locals>.do_actionz%s Startingr   N   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      ?)boolr   r   r   info_retry_aftertotal_secondsr	   r   	exceptionr   minr   sleep)r   r
   r   r   r   r   r   effective_is_runningr(   cur_intervalretriesexc
slack_timetoetelegram_excr   r&   r   network_retry_loop,   s^   ,"&r9   )__doc__r   r   collections.abcr   typingr   r   telegram._utils.loggingr   telegram.errorr   r   r   r	   __name__r   strfloatEventr+   intr9   r   r   r   r   <module>   s8   
	