B
    4\                 @   s   d dl mZmZmZ d dlmZmZ d dlmZ d dl	Z	d dl
Z
d dlmZ d dlZddlmZ ddl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)defaultdictdeque)	timedeltaN)gen   )_get_global_client)
log_errors)
get_workerc               @   s2   e Zd ZdZdd Zejd	ddZd
ddZdS )LockExtensionz An extension for the scheduler to manage Locks

    This adds the following routes to the scheduler

    *  lock_acquire
    *  lock_release
    c             C   s@   || _ tt| _t | _| j j| j| j	d | | j j
d< d S )N)lock_acquirelock_releaselocks)	schedulerr   r   eventsdictidsZhandlersupdateacquirerelease
extensions)selfr    r   /lib/python3.7/site-packages/distributed/lock.py__init__   s    
zLockExtension.__init__Nc       	   	   c   s   t   t|trt|}|| jkr*d}nx|| jkrtj }| j| 	| |
 }|d k	rrtt|d|}z0y
|V  W n tjk
r   d}P Y nX d}W d | j|  }||kstX q,W |r|| jkst|| j|< t|W d Q R X d S )NT)ZsecondsF)r   
isinstancelisttupler   tornador   ZEventr   appendwaitr   Zwith_timeoutr   TimeoutErrorpopleftAssertionErrorReturn)	r   streamnameidtimeoutresultZeventZfutureZevent2r   r   r   r   %   s.    




zLockExtension.acquirec          	   C   sv   t  f t|trt|}| j||kr2td| j|= | j| r`| jj	
| j| d j n| j|= W d Q R X d S )Nz#This lock has not yet been acquiredr   )r   r   r   r   r   get
ValueErrorr   r   ZloopZadd_callbackset)r   r'   r(   r)   r   r   r   r   B   s    

zLockExtension.release)NNNN)NNN)	__name__
__module____qualname____doc__r   r   	coroutiner   r   r   r   r   r   r      s
   
r   c               @   sh   e Zd ZdZdddZdddZdd	 Zd
d Zdd Zdd Z	e
jdd Ze
jdd Zdd ZdS )Locka   Distributed Centralized Lock

    Parameters
    ----------
    name: string
        Name of the lock to acquire.  Choosing the same name allows two
        disconnected processes to coordinate a lock.

    Examples
    --------
    >>> lock = Lock('x')  # doctest: +SKIP
    >>> lock.acquire(timeout=1)  # doctest: +SKIP
    >>> # do things with protected resource
    >>> lock.release()  # doctest: +SKIP
    Nc             C   s>   |pt  pt j| _|p$dt j | _t j| _d| _d S )Nzlock-F)	r
   r   clientuuidZuuid4hexr(   r)   _locked)r   r(   r5   r   r   r   r   _   s    zLock.__init__Tc             C   s@   |s|dk	rt dd}| jj| jjj| j| j|d}d| _|S )a   Acquire the lock

        Parameters
        ----------
        blocking : bool, optional
            If false, don't wait on the lock in the scheduler at all.
        timeout : number, optional
            Seconds to wait on the lock in the scheduler.  This does not
            include local coroutine time, network transfer time, etc..
            It is forbidden to specify a timeout when blocking is false.

        Examples
        --------
        >>> lock = Lock('x')  # doctest: +SKIP
        >>> lock.acquire(timeout=1)  # doctest: +SKIP

        Returns
        -------
        True or False whether or not it sucessfully acquired the lock
        Nz/can't specify a timeout for a non-blocking callr   )r(   r)   r*   T)r-   r5   syncr   r   r(   r)   r8   )r   Zblockingr*   r+   r   r   r   r   e   s    zLock.acquirec             C   s6   |   std| jj| jjj| j| jd}d| _|S )z& Release the lock if already acquired zLock is not yet acquired)r(   r)   F)	lockedr-   r5   r9   r   r   r(   r)   r8   )r   r+   r   r   r   r      s    zLock.releasec             C   s   | j S )N)r8   )r   r   r   r   r:      s    zLock.lockedc             C   s   |    | S )N)r   )r   r   r   r   	__enter__   s    zLock.__enter__c             O   s   |    d S )N)r   )r   argskwargsr   r   r   __exit__   s    zLock.__exit__c             c   s   |   V  t| d S )N)r   r   r&   )r   r   r   r   
__aenter__   s    
zLock.__aenter__c             o   s   |   V  d S )N)r   )r   r<   r=   r   r   r   	__aexit__   s    zLock.__aexit__c             C   s   t | jffS )N)r4   r(   )r   r   r   r   
__reduce__   s    zLock.__reduce__)NN)TN)r/   r0   r1   r2   r   r   r   r:   r;   r>   r   r3   r?   r@   rA   r   r   r   r   r4   O   s   

 	r4   )Z
__future__r   r   r   collectionsr   r   Zdatetimer   Zloggingr6   r    r   Ztornado.locksr5   r
   Zutilsr   Zworkerr   Z	getLoggerr/   Zloggerobjectr   r4   r   r   r   r   <module>   s   
=