U
    ~fhZ                     @  s   d Z ddlmZ ddlZddlZddlZddlZddlZddlm	Z	m
Z
 ddlmZmZ d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Optional)_ALock_create_lockFc                   @  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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floatr   zOptional[str])intervalmin_intervaltargetnamec                 C  sF   d| _ || _|| _|| _d| _d| _|| _d| _d| _t	t
 | _dS )a  Run a target function periodically on a background thread.

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

        :param interval: Seconds between calls to `target`.
        :param min_interval: Minimum seconds between calls if `wake` is
            called very often.
        :param target: A function.
        :param name: A name to give the underlying thread.
        FN)_event	_interval_min_interval_target_stopped_thread_name_skip_sleep_thread_will_exitr   r   _lock)selfr	   r
   r   r    r   J/tmp/pip-unpacked-wheel-36gvocj8/pymongo/asynchronous/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  sD   t jdkr2t }z||   W 5 |  X nt|   d S )Nwin32)sysplatformasyncioZSelectorEventLoopcloseZrun_until_complete_runrun)r   Zloopr   r   r   
_run_asyncC   s    
zPeriodicExecutor._run_asyncc              
   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 |s*trt	j
| j| jd}nt	j
| j| jd}d|_t|| _t|  z|  W nN tk
r( } z.dt|kst rd| _W Y 
dS  W 5 d}~X Y nX dS )zgStart. Multiple calls have no effect.

        Not safe to call from multiple threads at once.
        NF)r   r   Tzinterpreter shutdown)r   r   r   AssertionErrorjoinReferenceErrorr   is_alive_IS_SYNC	threadingThreadr,   r   r.   daemonweakrefproxy_register_executorstartRuntimeErrorr   r(   is_finalizing)r   startedthreader   r   r   openP   s8    
zPeriodicExecutor.open)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   rA   r   r   r   r+   |   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   r0   r1   r;   )r   rB   r   r   r   r0      s
    
zPeriodicExecutor.joinc                 C  s
   d| _ dS )z!Execute the target function soon.TN)r   r$   r   r   r   wake   s    zPeriodicExecutor.wakeint)new_intervalr   c                 C  s
   || _ d S rC   )r   )r   rF   r   r   r   update_interval   s    z PeriodicExecutor.update_intervalc                 C  s
   d| _ d S )NT)r   r$   r   r   r   
skip_sleep   s    zPeriodicExecutor.skip_sleepboolc              
     sT   | j 4 I d H 6 | jr0d| _W 5 Q I d H R  dS W 5 Q I d H R  dS Q I d H R X d S NTF)r   r   r   r$   r   r   r   _should_stop   s
    zPeriodicExecutor._should_stopc                   s   |   I d H sz|  I d H s(d| _W qW nB tk
rl   | j4 I d H  d| _d| _W 5 Q I d H R X  Y nX | jr|d| _n<t | j	 }| jst |k rt
| jI d H  | jrqqd| _q d S rJ   )rK   r   r   BaseExceptionr   r   r   time	monotonicr   r*   sleepr   r   )r   deadliner   r   r   r,      s$    zPeriodicExecutor._run)N)N)N)r"   
__module____qualname__r   r%   r.   r@   r+   r0   rD   rG   rH   rK   r,   r   r   r   r   r      s     ,r   r&   )executorr   c                 C  s   t | t}t| d S rC   )r7   ref_on_executor_deleted
_EXECUTORSadd)rS   rT   r   r   r   r9      s    r9   z'weakref.ReferenceType[PeriodicExecutor])rT   r   c                 C  s   t |  d S rC   )rV   remove)rT   r   r   r   rU      s    rU   r   c                  C  sV   t d krd S tt } | D ]}| }|r|  q| D ]}| }|r4|d q4d }d S )N   )rV   listr+   r0   )Z	executorsrT   rS   r   r   r   _shutdown_executors   s    
r[   )__doc__
__future__r   r*   r(   r4   rM   r7   typingr   r   Zpymongo.lockr   r   r3   r   setrV   r9   rU   r[   r   r   r   r   <module>   s    