B
    `R                 @   s   d dl mZmZmZ eZdZd dlZ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 d dlmZ yd dlZdZW n ek
r   dZY nX e ZG dd de Z!G dd deZ"G dd deZ#dS )    )absolute_importdivisionprint_functionag  
    author: Unknown (!UNKNOWN)
    name: memcached
    short_description: Use memcached DB for cache
    description:
        - This cache uses JSON formatted, per host records saved in memcached.
    requirements:
      - memcache (python lib)
    options:
      _uri:
        description:
          - List of connection information for the memcached DBs
        default: ['127.0.0.1:11211']
        type: list
        env:
          - name: ANSIBLE_CACHE_PLUGIN_CONNECTION
        ini:
          - key: fact_caching_connection
            section: defaults
      _prefix:
        description: User defined prefix to use when creating the DB entries
        default: ansible_facts
        env:
          - name: ANSIBLE_CACHE_PLUGIN_PREFIX
        ini:
          - key: fact_caching_prefix
            section: defaults
      _timeout:
        default: 86400
        description: Expiration timeout in seconds for the cache plugin data. Set to 0 to never expire
        env:
          - name: ANSIBLE_CACHE_PLUGIN_TIMEOUT
        ini:
          - key: fact_caching_timeout
            section: defaults
        type: integer
N)Lock)chain)	constants)AnsibleError)
MutableSet)BaseCacheModule)__version__)DisplayTFc               @   sX   e Zd Z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d ZdS )ProxyClientPoolz
    Memcached connection pooling for thread/fork safety. Inspired by py-redis
    connection pool.

    Available connections are maintained in a deque and released in a FIFO manner.
    c             O   s&   | dd| _|| _|| _|   d S )Nmax_connectionsi   )popr   connection_argsconnection_kwargsreset)selfargskwargs r   l/home/dcms/DCMS/lib/python3.7/site-packages/ansible_collections/community/general/plugins/cache/memcached.py__init__L   s    zProxyClientPool.__init__c             C   s4   t  | _d| _tj| jd| _t | _	t
 | _d S )Nr   )maxlen)osgetpidpid_num_connectionscollectionsdequer   _available_connectionsset_locked_connectionsr   _lock)r   r   r   r   r   R   s
    
zProxyClientPool.resetc          	   C   sF   | j t krB| j( | j t kr(d S |   |   W d Q R X d S )N)r   r   r   r#   disconnect_allr   )r   r   r   r   _check_safeY   s    zProxyClientPool._check_safec             C   sD   |    y| j }W n tk
r2   |  }Y nX | j| |S )N)r%   r    popleft
IndexErrorcreate_connectionr"   add)r   
connectionr   r   r   get_connectionb   s    zProxyClientPool.get_connectionc             C   s2   | j | jkrtd|  j d7  _ tj| j| jS )NzToo many memcached connections   )r   r   RuntimeErrormemcacheZClientr   r   )r   r   r   r   r(   k   s    z!ProxyClientPool.create_connectionc             C   s$   |    | j| | j| d S )N)r%   r"   remover    append)r   r*   r   r   r   release_connectionq   s    z"ProxyClientPool.release_connectionc             C   s$   xt | j| jD ]}|  qW d S )N)r   r    r"   r$   )r   connr   r   r   r$   v   s    zProxyClientPool.disconnect_allc                s    fdd}|S )Nc                 s   j  f| |S )N)_proxy_client)r   r   )namer   r   r   wrapped{   s    z,ProxyClientPool.__getattr__.<locals>.wrappedr   )r   r4   r5   r   )r4   r   r   __getattr__z   s    zProxyClientPool.__getattr__c          	   O   s*   |   }zt||||S | | X d S )N)r+   getattrr1   )r   r4   r   r   r2   r   r   r   r3      s    zProxyClientPool._proxy_clientN)__name__
__module____qualname____doc__r   r   r%   r+   r(   r1   r$   r6   r3   r   r   r   r   r   D   s   		r   c               @   sL   e Zd ZdZ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 )CacheModuleKeyszb
    A set subclass that keeps track of insertion time and persists
    the set in memcached.
    Zansible_cache_keysc             O   s   || _ t||| _d S )N)_cachedict_keyset)r   cacher   r   r   r   r   r      s    zCacheModuleKeys.__init__c             C   s
   || j kS )N)r?   )r   keyr   r   r   __contains__   s    zCacheModuleKeys.__contains__c             C   s
   t | jS )N)iterr?   )r   r   r   r   __iter__   s    zCacheModuleKeys.__iter__c             C   s
   t | jS )N)lenr?   )r   r   r   r   __len__   s    zCacheModuleKeys.__len__c             C   s$   t   | j|< | j| j| j d S )N)timer?   r=   r!   PREFIX)r   rA   r   r   r   r)      s    zCacheModuleKeys.addc             C   s   | j |= | j| j| j  d S )N)r?   r=   r!   rH   )r   rA   r   r   r   discard   s    zCacheModuleKeys.discardc             C   sX   x@t | j D ].}| j| }||  k r2|k rn q| j|= qW | j| j| j d S )N)listr?   keysr=   r!   rH   )r   Zs_minZs_maxktr   r   r   remove_by_timerange   s
    
z#CacheModuleKeys.remove_by_timerangeN)r8   r9   r:   r;   rH   r   rB   rD   rF   r)   rI   rN   r   r   r   r   r<      s   r<   c                   st   e Zd Z f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d Zdd Zdd Z  ZS )CacheModulec                s   dg}yBt t| j|| | dr.| d}| d| _| d| _W nH tk
r   tdsjt	dt
jr|t
jd}t
j| _t
j| _Y nX tst	di | _t|d	d
| _t| j| jtjpg | _d S )Nz127.0.0.1:11211Z_uri_timeout_prefixz2.9.zUDo not import CacheModules directly. Use ansible.plugins.loader.cache_loader instead.,z9python-memcached is required for the memcached fact cacher   )debug)superrO   r   
get_optionrP   rQ   KeyErroransible_base_version
startswithr   CZCACHE_PLUGIN_CONNECTIONsplitZCACHE_PLUGIN_TIMEOUTZCACHE_PLUGIN_PREFIXHAS_MEMCACHEr=   r   _dbr<   getrH   _keys)r   r   r   r*   )	__class__r   r   r      s&    


zCacheModule.__init__c             C   s   d | j|S )Nz{0}{1})formatrQ   )r   rA   r   r   r   	_make_key   s    zCacheModule._make_keyc             C   s*   | j dkr&t | j  }| jd| d S )Nr   )rP   rG   r^   rN   )r   Z
expiry_ager   r   r   _expire_keys   s    
zCacheModule._expire_keysc             C   sH   || j kr<| j| |}|d kr2| | t|| j |< | j |S )N)r=   r\   r]   ra   deleterV   )r   rA   valuer   r   r   r]      s    


zCacheModule.getc             C   s6   | j j| ||| jdd || j|< | j| d S )Nr,   )rG   Zmin_compress_len)r\   r!   ra   rP   r=   r^   r)   )r   rA   rd   r   r   r   r!      s    
zCacheModule.setc             C   s   |    tt| jS )N)rb   rJ   rC   r^   )r   r   r   r   rK      s    zCacheModule.keysc             C   s   |    || jkS )N)rb   r^   )r   rA   r   r   r   contains   s    zCacheModule.containsc             C   s*   | j |= | j| | | j| d S )N)r=   r\   rc   ra   r^   rI   )r   rA   r   r   r   rc      s    zCacheModule.deletec             C   s    x|   D ]}| | q
W d S )N)rK   rc   )r   rA   r   r   r   flush   s    zCacheModule.flushc             C   s
   | j  S )N)r^   copy)r   r   r   r   rg      s    zCacheModule.copyc             C   s   t  S )N)r>   )r   r   r   r   __getstate__   s    zCacheModule.__getstate__c             C   s   |    d S )N)r   )r   datar   r   r   __setstate__   s    zCacheModule.__setstate__)r8   r9   r:   r   ra   rb   r]   r!   rK   re   rc   rf   rg   rh   rj   __classcell__r   r   )r_   r   rO      s   rO   )$
__future__r   r   r   type__metaclass__ZDOCUMENTATIONr   r   rG   multiprocessingr   	itertoolsr   Zansibler   rY   Zansible.errorsr   Z/ansible.module_utils.common._collections_compatr	   Zansible.plugins.cacher
   Zansible.releaser   rW   Zansible.utils.displayr   r.   r[   ImportErrorZdisplayobjectr   r<   rO   r   r   r   r   <module>   s,   &
D$