U
    Z+d                     @   s   d Z ddlmZmZ ddlmZ ddlmZ ddlm	Z	 ddl
mZ dZd	gZd
ZdZe	ddZdd Zdd ZG dd dZeeedd dZG dd deZd	S )z-Memcached and in-memory cache result backend.    )bytes_to_strensure_bytes)cached_property)ImproperlyConfigured)LRUCache   )KeyValueStoreBackend)CacheBackendNzBThe Memcached backend requires either pylibmc or python-memcached.zYThe cache backend {0!r} is unknown,
Please use one of the following backends instead: {1}i  )limitc                  C   s|   t d d krtdt } }zdd l}d} W n> tk
rd   zdd l}W n tk
r^   ttY nX Y nX | ||ft d< t d S )Nr   FT)_impr   pylibmcImportErrormemcacher   REQUIRES_BACKEND)
is_pylibmcZmemcache_key_tr    r   9/tmp/pip-unpacked-wheel-ucduq0nd/celery/backends/cache.pyimport_best_memcache   s    
r   c                     s.   t  \}}}|j } |s& fdd}||fS )Nc                     s   | dd   | |S )NZ	behaviors)pop)argskwargsZ_Clientr   r   Client2   s    z!get_best_memcache.<locals>.Client)r   r   )r   r   r   r   key_tr   r   r   r   get_best_memcache+   s
    
r   c                   @   sF   e Zd Zdd Zdd Zdd Zdd Zd	d
 ZdddZdd Z	dS )DummyClientc                 O   s
   t | _d S N)_DUMMY_CLIENT_CACHEcache)selfr   r   r   r   r   __init__;   s    zDummyClient.__init__c                 O   s   | j |S r   )r   getr   keyr   r   r   r   r   r!   >   s    zDummyClient.getc                    s   | j   fdd|D S )Nc                    s   i | ]}| kr| | qS r   r   ).0kr   r   r   
<dictcomp>C   s       z)DummyClient.get_multi.<locals>.<dictcomp>r&   r   keysr   r&   r   	get_multiA   s    zDummyClient.get_multic                 O   s   || j |< d S r   r&   )r   r#   valuer   r   r   r   r   setE   s    zDummyClient.setc                 O   s   | j |d  d S r   )r   r   r"   r   r   r   deleteH   s    zDummyClient.deleter   c                 C   s   | j ||S r   )r   incr)r   r#   deltar   r   r   r.   K   s    zDummyClient.incrc                 C   s   d S r   r   )r   r#   expirer   r   r   touchN   s    zDummyClient.touchN)r   )
__name__
__module____qualname__r    r!   r*   r,   r-   r.   r1   r   r   r   r   r   9   s   
r   c                   C   s   t tfS r   )r   r   r   r   r   r   <lambda>V       r5   )r   Z	memcachedr   Zmemoryc                       s   e Zd ZdZdZdZdZdZd fdd	Zdd Z	dd	 Z
d
d Zdd Z fddZdd Zdd Zedd Zd fdd	Zdd Z  ZS )r	   zCache result backend.NTc           	   
      s   |si n|}t  j|f| || _t| jjjf|| _|pF|pF| jjj| _	| j	rv| j	
d\| _	}}|dd| _| j|td| _zt| j	  \| _| _W n, tk
r   tt| j	dtY nX |   d S )N:///;)typez, )superr    urldictappconfZcache_backend_optionsoptionsZcache_backendbackend	partitionrstripsplitserversZprepare_expiresintexpiresbackendsr   r   KeyErrorr   UNKNOWN_BACKENDformatjoinZ_encode_prefixes)	r   r>   rG   rA   r@   r<   r   _rE   	__class__r   r   r    b   s&     zCacheBackend.__init__c                 C   s   | j |S r   )clientr!   r   r#   r   r   r   r!   w   s    zCacheBackend.getc                 C   s   | j |S r   )rP   r*   r(   r   r   r   mgetz   s    zCacheBackend.mgetc                 C   s   | j ||| jS r   )rP   r,   rG   r   r#   r+   r   r   r   r,   }   s    zCacheBackend.setc                 C   s   | j |S r   )rP   r-   rQ   r   r   r   r-      s    zCacheBackend.deletec                    s4   |  |d }| jj|d| jd t j||f|S )Nr   )time)Zget_key_for_chordrP   r,   rG   r;   _apply_chord_incr)r   Zheader_result_argsbodyr   Z	chord_keyrN   r   r   rU      s     zCacheBackend._apply_chord_incrc                 C   s   | j |S r   )rP   r.   rQ   r   r   r   r.      s    zCacheBackend.incrc                 C   s   | j ||S r   )rP   r1   rS   r   r   r   r0      s    zCacheBackend.expirec                 C   s   | j | jf| jS r   )r   rE   r@   )r   r   r   r   rP      s    zCacheBackend.clientr   c                    sN   |si n|}d | j}| j d| d}||| j| jd t ||S )Nr9   r7   r8   )rA   rG   r@   )rL   rE   rA   updaterG   r@   r;   
__reduce__)r   r   r   rE   rA   rN   r   r   rX      s    zCacheBackend.__reduce__c                 O   s   d | j}| j d| dS )zcReturn the backend as an URI.

        This properly handles the case of multiple servers.
        r9   r7   r8   )rL   rE   rA   )r   r   r   rE   r   r   r   as_uri   s    zCacheBackend.as_uri)NNNN)r   N)r2   r3   r4   __doc__rE   Zsupports_autoexpireZsupports_native_joinZimplements_incrr    r!   rR   r,   r-   rU   r.   r0   r   rP   rX   rY   __classcell__r   r   rN   r   r	   Z   s(       

r	   )rZ   Zkombu.utils.encodingr   r   Zkombu.utils.objectsr   Zcelery.exceptionsr   Zcelery.utils.functionalr   baser   __all__r   r   rJ   r   r   r   r   rH   r	   r   r   r   r   <module>   s&   
