U
    ~fh                     @  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 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)_create_lockTc                   @  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  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.

        :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   _lock)selfr   r	   r
   r    r   I/tmp/pip-unpacked-wheel-36gvocj8/pymongo/synchronous/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   r@   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   r/   r0   r:   )r   rA   r   r   r   r/      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 rB   )r   )r   rE   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              	   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   _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 rI   )rJ   r   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$   r-   r?   r*   r/   rC   rF   rG   rJ   r+   r   r   r   r   r      s     ,r   r%   )executorr   c                 C  s   t | t}t| d S rB   )r6   ref_on_executor_deleted
_EXECUTORSadd)rR   rS   r   r   r   r8      s    r8   z'weakref.ReferenceType[PeriodicExecutor])rS   r   c                 C  s   t |  d S rB   )rU   remove)rS   r   r   r   rT      s    rT   r   c                  C  sV   t d krd S tt } | D ]}| }|r|  q| D ]}| }|r4|d q4d }d S )N   )rU   listr*   r/   )Z	executorsrS   rR   r   r   r   _shutdown_executors   s    
rZ   )__doc__
__future__r   r)   r'   r3   rL   r6   typingr   r   Zpymongo.lockr   r2   r   setrU   r8   rT   rZ   r   r   r   r   <module>   s    