U
    Zf6                     @   s   d dl Z d dlmZ ddlmZ ddlmZ ddlmZ dd	l	m
Z
 dd
lmZ dZG dd deZdd ZG dd deZdS )    N)copy_context   )BaseLongCallbackManager   )ProxySetProps   )context_value)AttributeDict)PreventUpdatez__$pending__c                       st   e Zd ZdZd fdd	Zdd Zdd Zd	d
 ZdddZdd Z	dd Z
dd Zdd Zdd Zdd Z  ZS )DiskcacheManagerz^Manage the background execution of callbacks with subprocesses and a diskcache result backend.Nc              
      s   zddl }ddl}ddl}W n, tk
rH } ztd|W 5 d}~X Y nX |dkr^| | _n t||j|jfsxtd|| _|| _	t
 | dS )a  
        Long callback manager that runs callback logic in a subprocess and stores
        results on disk using diskcache

        :param cache:
            A diskcache.Cache or diskcache.FanoutCache instance. See the diskcache
            documentation for information on configuration options. If not provided,
            a diskcache.Cache instance will be created with default values.
        :param cache_by:
            A list of zero-argument functions.  When provided, caching is enabled and
            the return values of these functions are combined with the callback
            function's input arguments and source code to generate cache keys.
        :param expire:
            If provided, a cache entry will be removed when it has not been accessed
            for ``expire`` seconds.  If not provided, the lifetime of cache entries
            is determined by the default behavior of the ``cache`` instance.
        r   Nz{DiskcacheLongCallbackManager requires extra dependencies which can be installed doing

    $ pip install "dash[diskcache]"
zHFirst argument must be a diskcache.Cache or diskcache.FanoutCache object)	diskcachepsutilmultiprocessImportErrorCachehandle
isinstanceZFanoutCache
ValueErrorexpiresuper__init__)selfcachecache_byr   r   r   r   Zmissing_imports	__class__ Q/tmp/pip-unpacked-wheel-47crqvv_/dash/long_callback/managers/diskcache_manager.pyr      s&    zDiskcacheManager.__init__c              
   C   s   dd l }|d krd S t|}| j  ||r||}|jddD ](}z|  W qH |jk
rn   Y qHX qHz|  W n |jk
r   Y nX z|	d W n |j
|jfk
r   Y nX W 5 Q R X d S )Nr   T)	recursiver   )r   intr   Ztransact
pid_existsProcesschildrenkillZNoSuchProcesswaitTimeoutExpired)r   jobr   processprocr   r   r   terminate_job;   s(    

zDiskcacheManager.terminate_jobc                 C   s:   dd l }t|}|r6||r6| |s6| | dS dS )Nr   TF)r   r   r    job_runningr)   )r   r&   r   r   r   r   terminate_unhealthy_jobY   s    

z(DiskcacheManager.terminate_unhealthy_jobc                 C   s:   dd l }t|}|r6||r6||}| |jkS dS )Nr   F)r   r   r    r!   statusZSTATUS_ZOMBIE)r   r&   r   r(   r   r   r   r*   e   s    
zDiskcacheManager.job_runningc                 C   s   t || j|S N)_make_job_fnr   )r   fnprogresskeyr   r   r   make_job_fno   s    zDiskcacheManager.make_job_fnc                 C   s   | j | d S r-   )r   deleter   r1   r   r   r   clear_cache_entryr   s    z"DiskcacheManager.clear_cache_entryc                 C   s4   ddl m} |||| |||fd}|  |jS )Nr   )r!   )targetargs)r   r!   _make_progress_keystartpid)r   r1   job_fnr7   contextr!   r(   r   r   r   call_job_fnv   s    zDiskcacheManager.call_job_fnc                 C   s*   |  |}| j|}|r&| j| |S r-   )r8   r   getr3   )r   r1   progress_keyZprogress_datar   r   r   get_progress   s
    
zDiskcacheManager.get_progressc                 C   s   | j |d k	S r-   )r   r>   r4   r   r   r   result_ready   s    zDiskcacheManager.result_readyc                 C   sp   | j || j}|| jkr | jS | jd kr6| | n| jrN| j j|| jd | | | |rl| | |S )N)r   )	r   r>   	UNDEFINEDr   r5   r   touchr8   r)   )r   r1   r&   resultr   r   r   
get_result   s    


zDiskcacheManager.get_resultc                 C   s6   |  |}| j|| j}|| jkr(i S | | |S r-   )Z_make_set_props_keyr   r>   rB   r5   )r   r1   Zset_props_keyrD   r   r   r   get_updated_props   s    


z"DiskcacheManager.get_updated_props)NNN)N)__name__
__module____qualname____doc__r   r)   r+   r*   r2   r5   r=   r@   rA   rE   rF   __classcell__r   r   r   r   r      s   +

r   c                    s    fdd}|S )Nc                    sV   fdd}r|gng fdd t  } fdd}|| d S )Nc                    s$   t | ttfs| g}  |  d S r-   )r   listtupleset)Zprogress_value)r   r?   r   r   _set_progress   s    z3_make_job_fn.<locals>.job_fn.<locals>._set_progressc                    s      d| |i d S )Nz
-set_props)rN   )Z_idprops)r   
result_keyr   r   
_set_props   s    z0_make_job_fn.<locals>.job_fn.<locals>._set_propsc               
      s   t f } d| _t | _t|  d}zDttr@}n*ttt	fr\ }nf }W nj t
k
r   d}ddi Y nD tk
r } z&d}dt|t di W 5 d }~X Y nX |s| d S )NFTZ_dash_no_updateZlong_callback_error)msgtb)r	   Zignore_register_pager   Zupdated_propsr   rN   r   dictrL   rM   r
   	Exceptionstr	traceback
format_exc)cZerroredZuser_callback_outputerr)rR   r   r<   r/   maybe_progressrQ   user_callback_argsr   r   run   s4    




z)_make_job_fn.<locals>.job_fn.<locals>.run)r   r^   )rQ   r?   r]   r<   rO   ctxr^   r   r/   r0   )rR   r<   r\   r?   rQ   r]   r   r;      s    z_make_job_fn.<locals>.job_fnr   )r/   r   r0   r;   r   r`   r   r.      s    /r.   c                   @   s   e Zd ZdZdS )DiskcacheLongCallbackManagerz<Deprecated: use `from dash import DiskcacheManager` instead.N)rG   rH   rI   rJ   r   r   r   r   ra      s   ra   )rX   Zcontextvarsr    r   Z_proxy_set_propsr   Z_callback_contextr   _utilsr	   
exceptionsr
   Z_pending_valuer   r.   ra   r   r   r   r   <module>   s    3