U
    /e>+                     @  s:  d Z ddlmZ ddlZeeZddlZddlZddl	m
Z
 ddlmZ ddlmZmZmZmZmZmZmZ ddlmZ ddlmZ d	d
lmZ dZddddZeg df Zeg ed f Zeeef Zeed eee  eeeef  f Z eg df Z!eee!f Z"eeee f Z#G dd dZ$G dd dZ%dS )z$ Internal utils related to Tornado

    )annotationsN)defaultdict)format_exception)Any	AwaitableCallableDictListSetUnion)gen)IOLoop   )ID Nonereturnc                  C  sH   t jdkrDt jd d dkrDdd l} t|  | jkrD| |   d S )Nwin32   )r      r   r   )	sysplatformversion_infoasynciotypeZget_event_loop_policyZWindowsProactorEventLoopPolicyZset_event_loop_policyZWindowsSelectorEventLoopPolicy)r   r   r   6/tmp/pip-unpacked-wheel-f5fndrjf/bokeh/util/tornado.pyfixup_windows_event_loop_policy<   s    r   c                   @  sp   e Zd ZU dZded< ded< ded< de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S )_AsyncPeriodicz Like ioloop.PeriodicCallback except the 'func' can be async and return
    a Future.

    Will wait for func to finish each time before we call it again. (Plain
    ioloop.PeriodicCallback can "pile up" invocations if they are taking too
    long.)

    r   _loopint_periodbool_started_stoppedCallbackr   )funcperiodio_loopr   c                 C  s"   || _ || _|| _d| _d| _d S )NF)_funcr   r!   r#   r$   )selfr&   r'   r(   r   r   r   __init__c   s
    z_AsyncPeriodic.__init__gen.Future[None]r   c                   s(   t   | j| jd  fdd  S )N     @@c                     s
     d S N)Z
set_resultr   fr   r   <lambda>o       z&_AsyncPeriodic.sleep.<locals>.<lambda>)r   ZFuturer   
call_laterr!   r*   r   r/   r   sleepm   s    z_AsyncPeriodic.sleepc                   sT   j rtdd_ ddfdd ddd	 fd
dj  d S )Nz&called start() twice on _AsyncPeriodicTInvokeResultr   c                    s4      }   }|d kr| S t|}t| |gS r.   )r5   r)   r   Zconvert_yieldedZmulti)Zsleep_futureresultZcallback_futurer4   r   r   invokew   s    
z$_AsyncPeriodic.start.<locals>.invoker,   r   )futurer   c                   sT   j sj   |  }|d k	rPtd t|j||j}td	| d S )Nz$Error thrown from periodic callback: )
r$   r   
add_future	exceptionlogerrorr   	__class____traceback__join)r9   exlinesr8   on_doner*   r   r   rE      s    
z%_AsyncPeriodic.start.<locals>.on_done)r#   RuntimeErrorr   r;   r5   r4   r   rD   r   startr   s    
z_AsyncPeriodic.startc                 C  s
   d| _ d S NT)r$   r4   r   r   r   stop   s    z_AsyncPeriodic.stopN)	__name__
__module____qualname____doc____annotations__r+   r5   rG   rI   r   r   r   r   r   T   s   
	
r   c                   @  s
  e Zd ZU dZded< ded< ded< ded< ded< ded	< d
ed< d
ddddZddddZdddddZddddddddZddddddZ	ddddd d!Z
ddd"d#d$Zd%d&ddd'd(d)Zddd"d*d+Zdd&ddd,d-d.Zddd"d/d0Zd1S )2_CallbackGroupz^ A collection of callbacks added to a Tornado IOLoop that can be removed
    as a group.

    Removers_next_tick_callback_removers_timeout_callback_removers_periodic_callback_removersRemoversByCallable_next_tick_removers_by_callable_timeout_removers_by_callable_periodic_removers_by_callabler   r   r   )r(   r   c                 C  sD   || _ i | _i | _i | _t | _tt| _	tt| _
tt| _d S r.   )r   rQ   rR   rS   	threadingLock_removers_lockr   setrU   rV   rW   )r*   r(   r   r   r   r+      s    


z_CallbackGroup.__init__r   c                 C  sR   t | jD ]}| | q
t | jD ]}| | q$t | jD ]}| | q>dS )z, Removes all registered callbacks.

        N)listrQ   remove_next_tick_callbackrR   remove_timeout_callbackrS   remove_periodic_callback)r*   Zcb_idr   r   r   remove_all_callbacks   s    z#_CallbackGroup.remove_all_callbacks)removersr   c                 C  s>   || j kr| jS || jkr | jS || jkr0| jS td|d S )NzUnhandled removers)rQ   rU   rR   rV   rS   rW   rF   )r*   ra   r   r   r   _get_removers_ids_by_callable   s    


z,_CallbackGroup._get_removers_ids_by_callabler%   r   Remover)callbackcallback_idra   removerr   c              	   C  s.   | j  ||krtd|||< W 5 Q R X d S )Nz?A callback of the same type has already been added with this ID)rZ   
ValueError)r*   rd   re   ra   rf   r   r   r   _assign_remover   s    z_CallbackGroup._assign_remover)re   ra   r   c              
   C  s   zp| j ` ||}t| | D ]<\}}z|| |sJ| ||= W q& tk
r`   Y q&X q&W 5 Q R X W n tk
r   tdY nX |  d S )Nz:Removing a callback twice (or after it's already been run))rZ   popr\   rb   itemsremoveKeyErrorrg   )r*   re   ra   rf   cbZcb_idsr   r   r   _execute_remover   s    

z_CallbackGroup._execute_remover)rd   re   r   c                   sR   dd fddd_ ddfdd} j| j S )	zu Adds a callback to be run on the nex

        The passed-in ID can be used with remove_next_tick_callback.

        zNone | Awaitable[None]r   c                     s   j r
d S    S r.   )removedr]   r   rd   re   r*   wrapperr   r   rq      s    
z6_CallbackGroup.add_next_tick_callback.<locals>.wrapperFr   c                     s
   d _ d S rH   )ro   r   )rq   r   r   rf      s    z6_CallbackGroup.add_next_tick_callback.<locals>.remover)ro   rh   rQ   r   Zadd_callback)r*   rd   re   rf   r   rp   r   add_next_tick_callback   s    z%_CallbackGroup.add_next_tick_callback)re   r   c                 C  s   |  || j dS )z@ Removes a callback added with add_next_tick_callback.

        N)rn   rQ   r*   re   r   r   r   r]      s    z(_CallbackGroup.remove_next_tick_callbackCallbackSyncr    )rd   timeout_millisecondsre   r   c                   sV   dd fdd}dddfdd}  j| j|d |S )	z Adds a callback to be run once after timeout_milliseconds.

        The passed-in ID can be used with remove_timeout_callback.

        r   r   c                     s       S r.   )r^   r   )rd   re   r*   r   r   rq     s    
z4_CallbackGroup.add_timeout_callback.<locals>.wrapperNc                     s    d k	rj   d S r.   )r   Zremove_timeoutr   )handler*   r   r   rf     s    z4_CallbackGroup.add_timeout_callback.<locals>.removerr-   )rh   rR   r   r3   )r*   rd   ru   re   rq   rf   r   )rd   re   rv   r*   r   add_timeout_callback   s    z#_CallbackGroup.add_timeout_callbackc                 C  s   |  || j dS )zN Removes a callback added with add_timeout_callback, before it runs.

        N)rn   rR   rs   r   r   r   r^     s    z&_CallbackGroup.remove_timeout_callback)rd   period_millisecondsre   r   c                 C  s0   t ||| jd}| ||| j|j |  dS )z Adds a callback to be run every period_milliseconds until it is removed.

        The passed-in ID can be used with remove_periodic_callback.

        )r(   N)r   r   rh   rS   rI   rG   )r*   rd   rx   re   rm   r   r   r   add_periodic_callback  s    z$_CallbackGroup.add_periodic_callbackc                 C  s   |  || j dS )z? Removes a callback added with add_periodic_callback.

        N)rn   rS   rs   r   r   r   r_     s    z'_CallbackGroup.remove_periodic_callbackN)rJ   rK   rL   rM   rN   r+   r`   rb   rh   rn   rr   r]   rw   r^   ry   r_   r   r   r   r   rO      s&   


rO   )&rM   
__future__r   logging	getLoggerrJ   r=   r   rX   collectionsr   	tracebackr   typingr   r   r   r   r	   r
   r   Ztornador   Ztornado.ioloopr   Z
core.typesr   __all__r   rt   ZCallbackAsyncr%   r6   rc   rP   rT   r   rO   r   r   r   r   <module>   s,   
$&>