from gluon.contrib.memcache.memcache import Client
import time

"""
examle of usage:

cache.memcache=MemcacheClient(request,[127.0.0.1:11211],debug=true)
"""

import cPickle as pickle
import thread

locker = thread.allocate_lock()

def MemcacheClient(*a, **b):
    locker.acquire()
    if not hasattr(MemcacheClient, '__mc_instance'):
        MemcacheClient.__mc_instance = _MemcacheClient(*a, **b)
    locker.release()
    return MemcacheClient.__mc_instance

class _MemcacheClient(Client): 
    def __init__(self, request, servers, debug=0, pickleProtocol=0,
                 pickler=pickle.Pickler, unpickler=pickle.Unpickler,
                 pload=None, pid=None):
        self.request=request
        Client.__init__(self,servers,debug,pickleProtocol,
                        pickler,unpickler,pload,pid)
    
    def __call__(self,key,f,time_expire=300):
        #key=self.__keyFormat__(key)
        value=None
        obj=self.get(key)
        if obj:
            value=obj
        elif f is None:
            if obj: self.delete(key)
        else:
            value=f()
            self.set(key,value,time_expire)
        return value
    
    def increment(self,key,value=1,time_expire=300):
        newKey=self.__keyFormat__(key)
        obj=self.get(newKey)
        if obj:
            return Client.incr(self,newKey,value)
        else:
            self.set(newKey,value,time_expire)
            return value
    
    def set(self,key,value,time_expire=300):
        newKey = self.__keyFormat__(key)
        return Client.set(self,newKey,value,time_expire)
    
    def get(self,key):
        newKey = self.__keyFormat__(key)
        return Client.get(self,newKey)
    
    def delete(self,key):
        newKey = self.__keyFormat__(key)
        return Client.delete(self,newKey)
    
    def __keyFormat__(self,key):
        return '%s/%s' % (self.request.application,key.replace(' ','_'))
        

[((13, 9, 13, 31), 'thread.allocate_lock', 'thread.allocate_lock', ({}, {}), '()', False, 'import thread\n'), ((27, 8, 28, 52), 'gluon.contrib.memcache.memcache.Client.__init__', 'Client.__init__', ({(27, 24, 27, 28): 'self', (27, 29, 27, 36): 'servers', (27, 37, 27, 42): 'debug', (27, 43, 27, 57): 'pickleProtocol', (28, 24, 28, 31): 'pickler', (28, 32, 28, 41): 'unpickler', (28, 42, 28, 47): 'pload', (28, 48, 28, 51): 'pid'}, {}), '(self, servers, debug, pickleProtocol, pickler, unpickler,\n    pload, pid)', False, 'from gluon.contrib.memcache.memcache import Client\n'), ((54, 15, 54, 56), 'gluon.contrib.memcache.memcache.Client.set', 'Client.set', ({(54, 26, 54, 30): 'self', (54, 31, 54, 37): 'newKey', (54, 38, 54, 43): 'value', (54, 44, 54, 55): 'time_expire'}, {}), '(self, newKey, value, time_expire)', False, 'from gluon.contrib.memcache.memcache import Client\n'), ((58, 15, 58, 38), 'gluon.contrib.memcache.memcache.Client.get', 'Client.get', ({(58, 26, 58, 30): 'self', (58, 31, 58, 37): 'newKey'}, {}), '(self, newKey)', False, 'from gluon.contrib.memcache.memcache import Client\n'), ((62, 15, 62, 41), 'gluon.contrib.memcache.memcache.Client.delete', 'Client.delete', ({(62, 29, 62, 33): 'self', (62, 34, 62, 40): 'newKey'}, {}), '(self, newKey)', False, 'from gluon.contrib.memcache.memcache import Client\n'), ((47, 19, 47, 49), 'gluon.contrib.memcache.memcache.Client.incr', 'Client.incr', ({(47, 31, 47, 35): 'self', (47, 36, 47, 42): 'newKey', (47, 43, 47, 48): 'value'}, {}), '(self, newKey, value)', False, 'from gluon.contrib.memcache.memcache import Client\n')]