SP/web2py/gluon/contrib/memcache/__init__.py
Saturneic 064f602b1a Add.
2018-10-25 23:33:13 +08:00

115 lines
3.7 KiB
Python

from gluon.contrib.memcache.memcache import Client
from gluon.cache import CacheAbstract
import time
"""
examle of usage:
cache.memcache = MemcacheClient(request,[127.0.0.1:11211],debug=true)
"""
import cPickle as pickle
import thread
from gluon import current
DEFAULT_TIME_EXPIRE = 300 # seconds (must be the same as cache.ram)
def MemcacheClient(*a, **b):
if not hasattr(current,'__memcache_client'):
current.__memcache_client = MemcacheClientObj(*a, **b)
return current.__memcache_client
class MemcacheClientObj(Client):
def initialize(self):
pass
meta_storage = {}
max_time_expire = 24*3600
def __init__(self, request, servers, debug=0, pickleProtocol=0,
pickler=pickle.Pickler, unpickler=pickle.Unpickler,
pload=None, pid=None,
default_time_expire = DEFAULT_TIME_EXPIRE):
self.request=request
self.default_time_expire = default_time_expire
if request:
app = request.application
else:
app = ''
Client.__init__(self, servers, debug, pickleProtocol,
pickler, unpickler, pload, pid)
if not app in self.meta_storage:
self.storage = self.meta_storage[app] = {
CacheAbstract.cache_stats_name: {
'hit_total': 0,
'misses': 0,
}}
else:
self.storage = self.meta_storage[app]
def __call__(self, key, f, time_expire = 'default'):
if time_expire == 'default':
time_expire = self.default_time_expire
if time_expire == None:
time_expire = self.max_time_expire
# this must be commented because get and set are redefined
# key = self.__keyFormat__(key)
now = time.time()
value = None
if f is None: # force deletion of value
self.delete(key)
return None
elif time_expire==0: # value forced expired
item = None # value to be computed
else:
item = self.get(key)
if item:
if not isinstance(item,(list,tuple)):
value = item
elif (item[0] < now - time_expire): # value expired
item = None # value to be computed
else:
value = item[1]
if not item:
value = f()
self.set(key, (now,value), self.max_time_expire)
return value
def increment(self, key, value=1, time_expire='default'):
""" time_expire is ignored """
if time_expire == 'default':
time_expire = self.default_time_expire
newKey = self.__keyFormat__(key)
obj = Client.get(self, newKey)
if obj:
if isinstance(obj,(int,float,long)):
return Client.incr(self, newKey, value)
else:
value += obj[1]
Client.set(self,newKey,(time.time(),value),
self.max_time_expire)
return value
else:
Client.set(self, newKey, value, self.max_time_expire)
return value
def set(self, key, value, time_expire='default'):
if time_expire == 'default':
time_expire = self.default_time_expire
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(' ', '_'))