U
    d                     @  s   d Z ddlmZ ddlZddlZddlZddlmZmZm	Z	 ddl
mZ G dd dZe Zddd	d
dZdddddZddddZdS )z-Run a target function on a background thread.    )annotationsN)AnyCallableOptional)_create_lockc                   @  s   e Zd Zd$dddddddZdd	d
dZdd	ddZd%dddddZd&dddddZdd	ddZdddddZ	dd	ddZ
dd	d d!Zdd	d"d#ZdS )'PeriodicExecutorNfloatzCallable[[], bool]zOptional[str])intervalmin_intervaltargetnamec                 C  sB   d| _ || _|| _|| _d| _d| _|| _d| _d| _t	 | _
dS )a   "Run a target function periodically on a background thread.

        If the target's return value is false, the executor stops.

        :Parameters:
          - `interval`: Seconds between calls to `target`.
          - `min_interval`: Minimum seconds between calls if `wake` is
            called very often.
          - `target`: A function.
          - `name`: A name to give the underlying thread.
        FN)_event	_interval_min_interval_target_stopped_thread_name_skip_sleep_thread_will_exitr   _lock)selfr	   r
   r   r    r   =/tmp/pip-unpacked-wheel-oblwsawz/pymongo/periodic_executor.py__init__   s    zPeriodicExecutor.__init__strreturnc                 C  s$   d| j j d| j dt| ddS )N<z(name=z) object at 0xx>)	__class____name__r   idr   r   r   r   __repr__=   s    zPeriodicExecutor.__repr__Nonec              	   C  s   | j J | jr@z| jdk	st| j  W n tk
r>   Y nX d| _d| _W 5 Q R X d}z| joj| j }W n tk
r   Y nX |stj	| j
| jd}d|_t|| _t|  |  dS )zgStart. Multiple calls have no effect.

        Not safe to call from multiple threads at once.
        NF)r   r   T)r   r   r   AssertionErrorjoinReferenceErrorr   is_alive	threadingThread_runr   daemonweakrefproxy_register_executorstart)r   startedthreadr   r   r   open@   s(    zPeriodicExecutor.openr   )dummyr   c                 C  s
   d| _ dS )zStop. To restart, call open().

        The dummy parameter allows an executor's close method to be a weakref
        callback; see monitor.py.
        TN)r   )r   r6   r   r   r   closea   s    zPeriodicExecutor.closezOptional[int])timeoutr   c              	   C  s8   | j d k	r4z| j | W n ttfk
r2   Y nX d S N)r   r(   r)   RuntimeError)r   r8   r   r   r   r(   i   s
    
zPeriodicExecutor.joinc                 C  s
   d| _ dS )z!Execute the target function soon.TN)r   r$   r   r   r   wakeq   s    zPeriodicExecutor.wakeint)new_intervalr   c                 C  s
   || _ d S r9   )r   )r   r=   r   r   r   update_intervalu   s    z PeriodicExecutor.update_intervalc                 C  s
   d| _ d S )NT)r   r$   r   r   r   
skip_sleepx   s    zPeriodicExecutor.skip_sleepboolc              	   C  s:   | j * | jr"d| _W 5 Q R  dS W 5 Q R  dS Q R X d S NTF)r   r   r   r$   r   r   r   Z__should_stop{   s
    zPeriodicExecutor.__should_stopc                 C  s   |   sz|  sd| _W qW n4 tk
rR   | j d| _d| _W 5 Q R X  Y nX | jrbd| _n6t | j	 }| jst |k rt
| j | jrpqqpd| _q d S rA   )_PeriodicExecutor__should_stopr   r   BaseExceptionr   r   r   time	monotonicr   sleepr   r   )r   deadliner   r   r   r-      s$    zPeriodicExecutor._run)N)N)N)r"   
__module____qualname__r   r%   r5   r7   r(   r;   r>   r?   rB   r-   r   r   r   r   r      s    !!r   r&   )executorr   c                 C  s   t | t}t| d S r9   )r/   ref_on_executor_deleted
_EXECUTORSadd)rJ   rK   r   r   r   r1      s    r1   z'weakref.ReferenceType[PeriodicExecutor])rK   r   c                 C  s   t |  d S r9   )rM   remove)rK   r   r   r   rL      s    rL   r   c                  C  sV   t d krd S tt } | D ]}| }|r|  q| D ]}| }|r4|d q4d }d S )N   )rM   listr7   r(   )Z	executorsrK   rJ   r   r   r   _shutdown_executors   s    
rR   )__doc__
__future__r   r+   rD   r/   typingr   r   r   Zpymongo.lockr   r   setrM   r1   rL   rR   r   r   r   r   <module>   s    