U
    /e#                     @  s   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Zd dlZd dl	Z	d dl
mZ d dlZd dlZeeZdZdd Zdd ZG d	d
 d
ZG dd dZdS )    )annotationsN)ClassVarz.dirlockc                   C  s   t jdS )Nz#distributed.worker.use-file-locking)daskconfigget r   r   9/tmp/pip-unpacked-wheel-g426oqom/distributed/diskutils.pyis_locking_enabled   s    r	   c              
   C  s^   zt |  W nJ tk
r"   Y n8 tk
rX } ztd|  d|  W 5 d }~X Y nX d S )NzFailed to remove z: )osunlinkFileNotFoundErrorOSErrorloggererror)pather   r   r   safe_unlink   s    r   c                   @  sH   e Zd ZU dZded< ded< ded< ddd	Zd
d Zedd ZdS )WorkDirz8
    A temporary work directory inside a WorkSpace.
    strdir_path
_lock_pathzweakref.finalize
_finalizerNc              	   C  sb  |d ks|d kst |d kr0tj||jd| _ntj|j|| _t| j t	 rDztj| jt
 | _tj| jr~t td| j z0|  t| j| _| j  W 5 Q R X W n, tk
r   tjd| jdd d | _Y nX W n( tk
r   tj| jdd  Y nX |j| j t| | j|| j| j| j| _nt| | j|d d | j| _d S )N)prefixdirzLocking %r...zyCould not acquire workspace lock on path: %s .Continuing without lock. This may result in workspaces not being cleaned upTexc_info)ignore_errors)AssertionErrortempfilemkdtempbase_dirr   r
   r   joinmkdirr	   DIR_LOCK_EXTr   existsr   debug_global_locklocket	lock_fileZ
_lock_fileacquirer   	exception	Exceptionshutilrmtree_known_locksaddweakreffinalize	_finalizer   )self	workspacenamer   r   r   r   __init__-   sR    
		     zWorkDir.__init__c                 C  s   |    dS )z,
        Dispose of this directory.
        N)r   )r3   r   r   r   release^   s    zWorkDir.releasec              	   C  sB   z|| W 5 |d k	r |   |d k	r<|j| t| X d S N)r7   r.   remover   _purge_directory)clsr4   	lock_pathr(   r   r   r   r   r2   d   s    zWorkDir._finalize)NN)	__name__
__module____qualname____doc____annotations__r6   r7   classmethodr2   r   r   r   r   r   $   s   

1r   c                   @  s   e Zd ZU dZded< ded< ded< e Zded< ddd	d
ZdddddZdd Z	dd Z
dd Zdd Zdd Zdd Zdd Zdd ZdS )	WorkSpacez
    An on-disk workspace that tracks disposable work directories inside it.
    If a process crashes or another event left stale directories behind,
    this will be detected and the directories purged.
    r   r    _global_lock_path_purge_lock_pathzClassVar[set[str]]r.   )r    c                 C  s4   |  || _tj| jd| _tj| jd| _d S )Nzglobal.lockz
purge.lock)_init_workspacer    r
   r   r!   rD   rE   )r3   r    r   r   r   r6      s    zWorkSpace.__init__)r    returnc                 C  s   t j|}|g}tjdkr4|| dt    |D ]f}zt | W nL tk
r   zt	j
|d W 5 Q R X W n tk
r   Y Y q8Y nX Y nX |  S t	j|d dS )zyCreate base_dir if it doesn't exist.
        If base_dir already exists but it's not writeable, change the name.
        win32-)r   )r   )r
   r   abspathsysplatformappendgetuidmakedirsFileExistsErrorr   TemporaryFilePermissionErrorr   )r3   r    Ztry_dirsZtry_dirr   r   r   rF      s    
zWorkSpace._init_workspacec                 K  s   t j| jf|S r8   )r'   r(   rD   r3   kwargsr   r   r   r&      s    zWorkSpace._global_lockc                 K  s   t j| jf|S r8   )r'   r(   rE   rS   r   r   r   _purge_lock   s    zWorkSpace._purge_lockc                 C  s   t  s
g S | jdd}z|  W n tjk
r<   g  Y S X zt|  }W 5 |  X g }| jdd}z|  W n tjk
r   Y n0X z"|D ]}| 	|r|
| qW 5 |  X |S )Nr   timeout)r	   r&   r)   r'   	LockErrorr7   list_list_unknown_locksrU   _check_lock_or_purgerM   )r3   lock
candidatesZpurgedr   r   r   r   _purge_leftovers   s,    



zWorkSpace._purge_leftoversc              	   c  sZ   t  tj| jdt D ]:}zt|}W n tk
r@   Y qX t|j	r|V  qd S )N*)
globr
   r   r!   r    r#   statr   S_ISREGst_mode)r3   pstr   r   r   rZ      s    zWorkSpace._list_unknown_locksc                 C  s   t j|| jd d S )N)onerror)r,   r-   _on_remove_error)r3   r   r   r   r   r:      s    zWorkSpace._purge_directoryc                 C  s   | tst|| jkrdS td| tj|dd}z|  W n tj	k
rZ   Y dS X z8|dtt  }tj|rtd| | | W 5 |
  X t| dS )z
        Try locking the given path, if it fails it's in use,
        otherwise the corresponding directory is deleted.

        Return True if the lock was stale.
        FzChecking lock file %r...r   rV   Nz/Found stale lock file and directory %r, purgingT)endswithr#   r   r.   r   r%   r'   r(   r)   rX   r7   lenr
   r   r$   infor:   r   )r3   r<   r\   r   r   r   r   r[      s"    

zWorkSpace._check_lock_or_purgec                 C  s"   |\}}}t d||t| d S )Nz&Failed to remove %r (failed in %r): %s)r   r   r   )r3   funcr   r   typexctbr   r   r   rg      s    
zWorkSpace._on_remove_errorc                 K  s<   z|    W n" tk
r.   tjddd Y nX t| f|S )a  
        Create and return a new WorkDir in this WorkSpace.
        Either the *prefix* or *name* parameter should be given
        (*prefix* is preferred as it avoids potential collisions)

        Parameters
        ----------
        prefix : str (optional)
            The prefix of the temporary subdirectory name for the workdir
        name : str (optional)
            The subdirectory name for the workdir
        z<Failed to clean up lingering worker directories in path: %s Tr   )r^   r   r   r   r   rS   r   r   r   new_work_dir   s    zWorkSpace.new_work_dirN)r=   r>   r?   r@   rA   setr.   r6   rF   r&   rU   r^   rZ   r:   r[   rg   ro   r   r   r   r   rC   p   s   
'rC   )
__future__r   r`   loggingr
   r,   ra   rK   r   r0   typingr   r'   r   	getLoggerr=   r   r#   r	   r   r   rC   r   r   r   r   <module>   s"   

L