o
    i'                     @   sR   d dl Z d dlZd dlmZmZmZ G dd dZde jdefddZd	d
 Z	dS )    N)AnyCallable	Coroutinec                	   @   s   e Zd ZdZdd Zdd Zdd Zded	efd
dZ	ded	efddZ
dededeeeef f fddZdejded	efddZdejded	efddZdejded	efddZdS )BackgroundSchedulerzf
    Schedules background tasks execution either in separate thread or in the running event loop.
    c                 C   s    d | _ g | _t | _d| _d S )NF)_next_timer_event_loops	threadingLock_lock_stoppedself r   D/home/ubuntu/.local/lib/python3.10/site-packages/redis/background.py__init__   s   

zBackgroundScheduler.__init__c                 C   s   |    d S N)stopr   r   r   r   __del__   s   zBackgroundScheduler.__del__c                 C   s   | j 8 | jr	 W d   dS d| _| jr| j  d| _| jD ]}| r-||j q!| j  W d   dS 1 s>w   Y  dS )zB
        Stop all scheduled tasks and clean up resources.
        NT)	r
   r   r   cancelr   
is_runningcall_soon_threadsafer   clear)r   loopr   r   r   r      s   

"zBackgroundScheduler.stopdelaycallbackc                 G      | j  | jr	 W d   dS W d   n1 sw   Y  t }| j  | j| W d   n1 s7w   Y  tjt|| j	||g|R dd}|
  dS )zI
        Runs callable task once after certain delay in seconds.
        NTtargetargsdaemon)r
   r   asyncionew_event_loopr   appendr   Thread_start_event_loop_in_thread_call_laterstart)r   r   r   r   r   threadr   r   r   run_once(       zBackgroundScheduler.run_onceintervalc                 G   r   )zN
        Runs recurring callable task with given interval in seconds.
        NTr   )r
   r   r    r!   r   r"   r   r#   r$   _call_later_recurringr&   )r   r*   r   r   r   r'   r   r   r   run_recurring=   r)   z!BackgroundScheduler.run_recurringcoro.c                    s   j  jr	 W d   dS W d   n1 sw   Y  t t|g|R   fdd _dS )z
        Runs recurring coroutine with given interval in seconds in the current event loop.
        To be used only from an async context. No additional threads are created.
        Nc                      sV   j  jr	 W d    d S W d    n1 sw   Y     _d S r   r
   r   
call_laterr   r   r*   r   r   tickwrappedr   r   r1   `   s   z5BackgroundScheduler.run_recurring_async.<locals>.tick)r
   r   r    get_running_loop_async_to_sync_wrapperr/   r   )r   r*   r-   r   r   r0   r   run_recurring_asyncR   s   
z'BackgroundScheduler.run_recurring_asyncr   c                 G   sX   | j  | jr	 W d    d S W d    n1 sw   Y  |j||g|R  | _d S r   r.   )r   r   r   r   r   r   r   r   r%   l   s   zBackgroundScheduler._call_laterc                 G   s`   | j  | jr	 W d    d S W d    n1 sw   Y  | j||| j|||g|R   d S r   )r
   r   r%   _execute_recurringr   r   r*   r   r   r   r   r   r+   t   s   z)BackgroundScheduler._call_later_recurringc                 G   s   | j  | jr	 W d   dS W d   n1 sw   Y  z||  W n	 ty.   Y nw | j  | jr?	 W d   dS W d   n1 sIw   Y  | j||| j|||g|R   dS )zR
        Executes recurring callable task with given interval in seconds.
        N)r
   r   	Exceptionr%   r6   r7   r   r   r   r6      s,   
z&BackgroundScheduler._execute_recurringN)__name__
__module____qualname____doc__r   r   r   floatr   r(   r,   r   r   r5   r    AbstractEventLoopr%   r+   r6   r   r   r   r   r      sB    


r   
event_loopcall_soon_cbc                 G   s
  t |  | j|| g|R   z>|   W z3zt | }|D ]}|  q| t j|ddi W n	 ty:   Y nw W | 	  dS W | 	  dS | 	  w z1zt | }|D ]}|  qW| t j|ddi W n	 tys   Y nw W | 	  w W | 	  w | 	  w )z
    Starts event loop in a thread and schedule callback as soon as event loop is ready.
    Used to be able to schedule tasks using loop.call_later.

    :param event_loop:
    :return:
    return_exceptionsTN)
r    set_event_loop	call_soonrun_forever	all_tasksr   run_until_completegatherr8   close)r?   r@   r   pendingtaskr   r   r   r$      s@   







r$   c                    s    fdd}|S )a  
    Wraps an asynchronous function so it can be used with loop.call_later.

    :param loop: The event loop in which the coroutine will be executed.
    :param coro_func: The coroutine function to wrap.
    :param args: Positional arguments to pass to the coroutine function.
    :param kwargs: Keyword arguments to pass to the coroutine function.
    :return: A regular function suitable for loop.call_later.
    c                      s   t j i d d S )N)r   )r    ensure_futurer   r   	coro_funckwargsr   r   r   r2      s   z'_async_to_sync_wrapper.<locals>.wrappedr   )r   rM   r   rN   r2   r   rL   r   r4      s   r4   )
r    r   typingr   r   r   r   r>   r$   r4   r   r   r   r   <module>   s     
