U
    Zf                     @   s   d dl Z 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 dlmZ G d	d
 d
eZdd ZG dd deZdS )    N)copy_context)PlotlyJSONEncoder)context_value)AttributeDict)PreventUpdate)ProxySetProps)BaseLongCallbackManagerc                       s|   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dd Z  ZS )CeleryManagerz=Manage background execution of callbacks with a celery queue.Nc              
      s   zddl }ddlm} W n, tk
rD } ztd|W 5 d}~X Y nX t||jsZtdt|j|rntd|| _|| _	t
 | dS )a  
        Long callback manager that runs callback logic on a celery task queue,
        and stores results using a celery result backend.

        :param celery_app:
            A celery.Celery application instance that must be configured with a
            result backend. See the celery documentation for information on
            configuration options.
        :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 celery result backend.
        r   N)DisabledBackendzuCeleryLongCallbackManager requires extra dependencies which can be installed doing

    $ pip install "dash[celery]"
z-First argument must be a celery.Celery objectz8Celery instance must be configured with a result backend)celeryZcelery.backends.baser
   ImportError
isinstanceZCelery
ValueErrorbackendhandleexpiresuper__init__)self
celery_appcache_byr   r   r
   Zmissing_imports	__class__ N/tmp/pip-unpacked-wheel-47crqvv_/dash/long_callback/managers/celery_manager.pyr      s     zCeleryManager.__init__c                 C   s   |d krd S | j j| d S N)r   control	terminater   jobr   r   r   terminate_job:   s    zCeleryManager.terminate_jobc                 C   s&   |  |}|r"|jdkr"| |S dS )N)FAILUREZREVOKEDF)get_taskstatusr    )r   r   taskr   r   r   terminate_unhealthy_job@   s    

z%CeleryManager.terminate_unhealthy_jobc                 C   s   |  |}|o|jdkS )N)ZPENDINGZRECEIVEDZSTARTEDRETRYZPROGRESS)r"   r#   )r   r   futurer   r   r   job_runningF   s    
zCeleryManager.job_runningc                 C   s   t || j||S r   )_make_job_fnr   )r   fnprogresskeyr   r   r   make_job_fnP   s    zCeleryManager.make_job_fnc                 C   s   |r| j |S d S r   )r   ZAsyncResultr   r   r   r   r"   S   s    zCeleryManager.get_taskc                 C   s   | j j| d S r   )r   r   deleter   r,   r   r   r   clear_cache_entryY   s    zCeleryManager.clear_cache_entryc                 C   s   | || |||}|jS r   )delay_make_progress_keyZtask_id)r   r,   job_fnargscontextr$   r   r   r   call_job_fn\   s    zCeleryManager.call_job_fnc                 C   s8   |  |}| jj|}|r4| jj| t|S d S r   )r2   r   r   getr.   jsonloads)r   r,   progress_keyZprogress_datar   r   r   get_progress`   s    

zCeleryManager.get_progressc                 C   s   | j j|d k	S r   )r   r   r7   r/   r   r   r   result_readyi   s    zCeleryManager.result_readyc                 C   sr   | j j|}|d kr| jS t|}| jd kr<| | n| jrT| j j|| j | | 	| | 
| |S r   )r   r   r7   	UNDEFINEDr8   r9   r   r0   r   r2   r    )r   r,   r   resultr   r   r   
get_resultl   s    


zCeleryManager.get_resultc                 C   s4   | j j| |}|d kr i S | | t|S r   )r   r   r7   Z_make_set_props_keyr0   r8   r9   )r   r,   updated_propsr   r   r   get_updated_props   s
    
zCeleryManager.get_updated_props)NN)N)__name__
__module____qualname____doc__r   r    r%   r(   r-   r"   r0   r6   r;   r<   r?   rA   __classcell__r   r   r   r   r	      s   )

	r	   c                    s.   |j  |jd| dd fdd	}|S )NZlong_callback_)namec                    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}  tj| td d S )Ncls)r   listtuplesetr8   dumpsr   )Zprogress_value)cacher:   r   r   _set_progress   s    z3_make_job_fn.<locals>.job_fn.<locals>._set_progressc                    s$      dtj| |itd d S )Nz
-set_propsrH   )rL   r8   rM   r   )Z_idprops)rN   
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 nz t
k
r   d}tjdditd Y nJ tk
r } z,d}tdt|t di W 5 d }~X Y nX |stj|td d S )NFTZ_dash_no_updaterH   Zlong_callback_error)msgtb)r   Zignore_register_pager   r@   r   rL   r   dictrJ   rK   r   r8   rM   r   	Exceptionstr	traceback
format_exc)cZerroredZuser_callback_outputerr)rR   rN   r5   r*   maybe_progressrQ   user_callback_argsr   r   run   sJ    



  z)_make_job_fn.<locals>.job_fn.<locals>.run)r   r^   )rQ   r:   r]   r5   rO   ctxr^   rN   r*   r+   )rR   r5   r\   r:   rQ   r]   r   r3      s    )z_make_job_fn.<locals>.job_fn)N)r   r$   )r*   r   r+   r,   r3   r   r`   r   r)      s    <r)   c                   @   s   e Zd ZdZdS )CeleryLongCallbackManagerz9Deprecated: use `from dash import CeleryManager` instead.N)rB   rC   rD   rE   r   r   r   r   ra      s   ra   )r8   rX   Zcontextvarsr   Z_plotly_utils.utilsr   Zdash._callback_contextr   Zdash._utilsr   Zdash.exceptionsr   Z#dash.long_callback._proxy_set_propsr   Zdash.long_callback.managersr   r	   r)   ra   r   r   r   r   <module>   s   |C