B
    F.\S%                 @   s   d dl mZmZmZ d dlmZ d dlZd dlZd dlZd dl	m
Z
 d dlZ	ddlmZmZmZ ddlmZmZmZ ddlmZ eeZG d	d
 d
eZG dd deZdS )    )print_functiondivisionabsolute_import)defaultdictN)gen   )Future_get_global_clientClient)tokeysyncthread_state)
get_clientc               @   s`   e Zd ZdZdd ZdddZddd	Zejdd
dZ	dddZ
ejdddZdddZdS )QueueExtensionz An extension for the scheduler to manage queues

    This adds the following routes to the scheduler

    *  queue_create
    *  queue_release
    *  queue_put
    *  queue_get
    *  queue_size
    c             C   sl   || _ t | _t | _tdd | _| j j| j| j	| j
| jd | j j| j| jd | | j jd< d S )Nc               S   s   dS )Nr    r   r   r   1lib/python3.7/site-packages/distributed/queues.py<lambda>"   s    z)QueueExtension.__init__.<locals>.<lambda>)queue_create	queue_put	queue_getqueue_qsize)zqueue-future-releasequeue_releasequeues)	schedulerdictr   client_refcountr   future_refcountZhandlersupdatecreateputgetqsizeZstream_handlersfuture_releaserelease
extensions)selfr   r   r   r   __init__   s    zQueueExtension.__init__Nr   c             C   s@   || j kr*tj j|d| j |< d| j|< n| j|  d7  < d S )N)maxsizer   )r   tornadoQueuer   )r%   streamnameclientr'   r   r   r   r   2   s    
zQueueExtension.createc             C   sl   || j krd S | j|  d8  < | j| dkrh| j|= | j | j}| j |= | jjdd |D d| d d S )Nr   r   c             S   s    g | ]}|d  dkr|d qS )typer   valuer   ).0dr   r   r   
<listcomp>C   s    z*QueueExtension.release.<locals>.<listcomp>zqueue-%s)keysr,   )r   r   Z_queuer   client_releases_keys)r%   r*   r+   r,   Zfuturesr   r   r   r#   9   s    
zQueueExtension.releasec             c   sx   |d k	r@d|d}| j ||f  d7  < | jj|gd| d n
d|d}|d k	r^tj|d}| j| j||dV  d S )	Nr   )r-   r.   r   zqueue-%s)r2   r,   Zmsgpack)seconds)timeout)r   r   Zclient_desires_keysdatetime	timedeltar   r   )r%   r*   r+   keydatar,   r5   recordr   r   r   r   G   s    

zQueueExtension.putc             C   sN   | j ||f  d8  < | j ||f dkrJ| jj|gd| d | j ||f= d S )Nr   r   zqueue-%s)r2   r,   )r   r   r3   )r%   r+   r8   r,   r   r   r   r"   S   s
    
zQueueExtension.future_releaseFc             #   s   fdd |rj | }g }|dkrJx\| sF| V }|| q(W n:|d k	r^d}	t|	x$t|D ]}
| V }|| qhW  fdd|D }t|n:|d k	rtj	|d}j | j|dV } |}t|d S )	Nc                sh   | d dkrd|   } | d } jj|}|dk	r8|jnd}|| d< |dkrd|jj| d< |jj| d	< | S )
z Add task status if known r-   r   r.   NZloststateerred	exception	traceback)copyr   Ztasksr    r;   Zexception_blamer=   r>   )r:   r8   Ztsr;   )r%   r   r   process]   s    z#QueueExtension.get.<locals>.processTzNDask queues don't support simultaneous use of integer batch sizes and timeoutsc                s   g | ]} |qS r   r   )r/   o)r@   r   r   r1   {   s    z&QueueExtension.get.<locals>.<listcomp>)r4   )r5   )
r   emptyr    appendNotImplementedErrorranger   Returnr6   r7   )r%   r*   r+   r,   r5   batchqoutr:   msgir   )r@   r%   r   r    Z   s*    



zQueueExtension.getc             C   s   | j |  S )N)r   r!   )r%   r*   r+   r,   r   r   r   r!      s    zQueueExtension.qsize)NNNr   )NNN)NNNNNN)NNN)NNNNF)NNN)__name__
__module____qualname____doc__r&   r   r#   r   	coroutiner   r"   r    r!   r   r   r   r   r      s   



 (r   c               @   s   e Zd ZdZdddZdd Zejddd	Zdd
dZ	dddZ
dd ZejdddZejdd Zdd Zdd Zdd ZdS ) r)   a   Distributed Queue

    This allows multiple clients to share futures or small bits of data between
    each other with a multi-producer/multi-consumer queue.  All metadata is
    sequentialized through the scheduler.

    Elements of the Queue must be either Futures or msgpack-encodable data
    (ints, strings, lists, dicts).  All data is sent through the scheduler so
    it is wise not to send large objects.  To share large objects scatter the
    data and share the future instead.

    .. warning::

       This object is experimental and has known issues in Python 2

    Examples
    --------
    >>> from dask.distributed import Client, Queue  # doctest: +SKIP
    >>> client = Client()  # doctest: +SKIP
    >>> queue = Queue('x')  # doctest: +SKIP
    >>> future = client.submit(f, x)  # doctest: +SKIP
    >>> queue.put(future)  # doctest: +SKIP

    See Also
    --------
    Variable: shared variable between clients
    Nr   c             C   st   |pt  | _|pdt j | _| jjs4ttddrL| jj	j
| j|d| _n$t| jj| jj	j
| j|d tj| _d S )Nzqueue-Zon_event_loop_threadF)r+   r'   )r	   r,   uuidZuuid4hexr+   Zasynchronousgetattrr   r   r   _startedr   Zloopr   Zmoment)r%   r+   r,   r'   r   r   r   r&      s    zQueue.__init__c                s   t j fdd}|  S )Nc               3   s    j V  t d S )N)rT   r   rF   r   )r%   r   r   _   s    zQueue.__await__.<locals>._)r   rP   	__await__)r%   rU   r   )r%   r   rV      s    zQueue.__await__c             c   sF   t |tr*| jjjt|j|| jdV  n| jjj||| jdV  d S )N)r8   r5   r+   )r9   r5   r+   )
isinstancer   r,   r   r   r   r8   r+   )r%   r.   r5   r   r   r   _put   s    

z
Queue._putc             K   s   | j j| j|fd|i|S )z Put data into the queue r5   )r,   r   rX   )r%   r.   r5   kwargsr   r   r   r      s    z	Queue.putFc             K   s   | j j| jf||d|S )a   Get data from the queue

        Parameters
        ----------
        timeout: Number (optional)
            Time in seconds to wait before timing out
        batch: boolean, int (optional)
            If True then return all elements currently waiting in the queue.
            If an integer than return that many elements from the queue
            If False (default) then return one item at a time
         )r5   rG   )r,   r   _get)r%   r5   rG   rY   r   r   r   r       s    z	Queue.getc             K   s   | j j| jf|S )z) Current number of elements in the queue )r,   r   _qsize)r%   rY   r   r   r   r!      s    zQueue.qsizec             #   sR    j jj| j|dV } fdd}|dkr6||}ntt||}t|d S )N)r5   r+   rG   c                sp   | d dkrdt | d  jd| d d}| d dkrH|j| d | d	   jd
 j| d d n| d }|S )Nr-   r   r.   Tr;   )Zinformr;   r<   r=   r>   zqueue-future-release)opr+   r8   )r   r,   Z_stateZ	set_error_send_to_schedulerr+   )r0   r.   )r%   r   r   r@      s    zQueue._get.<locals>.processF)r,   r   r   r+   listmapr   rF   )r%   r5   rG   Zrespr@   resultr   )r%   r   rZ      s    


z
Queue._getc             c   s"   | j jj| jdV }t|d S )N)r+   )r,   r   r   r+   r   rF   )r%   r`   r   r   r   r[      s    zQueue._qsizec             C   s$   | j jdkr | j d| jd d S )NZrunningr   )r\   r+   )r,   Zstatusr]   r+   )r%   r   r   r   close   s    zQueue.closec             C   s   | j | jjjfS )N)r+   r,   r   address)r%   r   r   r   __getstate__   s    zQueue.__getstate__c          	   C   s\   |\}}yt |}|jj|ks"tW n$ ttfk
rH   t|dd}Y nX | j||d d S )NF)Zset_as_default)r+   r,   )r   r   rb   AssertionErrorAttributeErrorr
   r&   )r%   r;   r+   rb   r,   r   r   r   __setstate__  s    zQueue.__setstate__)NNr   )N)N)NF)NF)rL   rM   rN   rO   r&   rV   r   rP   rX   r   r    r!   rZ   r[   ra   rc   rf   r   r   r   r   r)      s   



r)   )Z
__future__r   r   r   collectionsr   r6   ZloggingrQ   r(   r   Ztornado.queuesr,   r   r	   r
   Zutilsr   r   r   Zworkerr   Z	getLoggerrL   Zloggerobjectr   r)   r   r   r   r   <module>   s   
v