|
@@ -1,151 +0,0 @@
|
|
|
-#-*- coding:utf-8 -*-
|
|
|
-
|
|
|
-'''from douban code, cool '''
|
|
|
-
|
|
|
-import inspect
|
|
|
-from functools import wraps
|
|
|
-import time
|
|
|
-
|
|
|
-try:
|
|
|
- import cPickle as pickle
|
|
|
-except:
|
|
|
- import pickle
|
|
|
-
|
|
|
-from .empty import Empty
|
|
|
-from .format import format
|
|
|
-
|
|
|
-from rrd.store import mc
|
|
|
-
|
|
|
-# some time consts for mc expire
|
|
|
-HALF_HOUR = 1800
|
|
|
-ONE_HOUR = 3600
|
|
|
-HALF_DAY = ONE_HOUR * 12
|
|
|
-ONE_DAY = ONE_HOUR * 24
|
|
|
-ONE_WEEK = ONE_DAY * 7
|
|
|
-ONE_MONTH = ONE_DAY * 30
|
|
|
-
|
|
|
-
|
|
|
-def gen_key(key_pattern, arg_names, defaults, *a, **kw):
|
|
|
- return gen_key_factory(key_pattern, arg_names, defaults)(*a, **kw)
|
|
|
-
|
|
|
-
|
|
|
-def gen_key_factory(key_pattern, arg_names, defaults):
|
|
|
- args = dict(zip(arg_names[-len(defaults):], defaults)) if defaults else {}
|
|
|
- if callable(key_pattern):
|
|
|
- names = inspect.getargspec(key_pattern)[0]
|
|
|
- def gen_key(*a, **kw):
|
|
|
- aa = args.copy()
|
|
|
- aa.update(zip(arg_names, a))
|
|
|
- aa.update(kw)
|
|
|
- if callable(key_pattern):
|
|
|
- key = key_pattern(*[aa[n] for n in names])
|
|
|
- else:
|
|
|
- key = format(key_pattern, *[aa[n] for n in arg_names], **aa)
|
|
|
- return key and key.replace(' ','_'), aa
|
|
|
- return gen_key
|
|
|
-
|
|
|
-def cache_(key_pattern, mc, expire=0, max_retry=0):
|
|
|
- def deco(f):
|
|
|
- arg_names, varargs, varkw, defaults = inspect.getargspec(f)
|
|
|
- if varargs or varkw:
|
|
|
- raise Exception("do not support varargs")
|
|
|
- gen_key = gen_key_factory(key_pattern, arg_names, defaults)
|
|
|
- @wraps(f)
|
|
|
- def _(*a, **kw):
|
|
|
- key, args = gen_key(*a, **kw)
|
|
|
- if not key:
|
|
|
- return f(*a, **kw)
|
|
|
- if isinstance(key, unicode):
|
|
|
- key = key.encode("utf8")
|
|
|
- r = mc.get(key)
|
|
|
-
|
|
|
- # anti miss-storm
|
|
|
- retry = max_retry
|
|
|
- while r is None and retry > 0:
|
|
|
- time.sleep(0.1)
|
|
|
- r = mc.get(key)
|
|
|
- retry -= 1
|
|
|
- r = pickle.loads(r) if r else None
|
|
|
-
|
|
|
- if r is None:
|
|
|
- r = f(*a, **kw)
|
|
|
- if r is not None:
|
|
|
- mc.set(key, pickle.dumps(r), expire)
|
|
|
-
|
|
|
- if isinstance(r, Empty):
|
|
|
- r = None
|
|
|
- return r
|
|
|
- _.original_function = f
|
|
|
- return _
|
|
|
- return deco
|
|
|
-
|
|
|
-def pcache_(key_pattern, mc, count=300, expire=0, max_retry=0):
|
|
|
- def deco(f):
|
|
|
- arg_names, varargs, varkw, defaults = inspect.getargspec(f)
|
|
|
- if varargs or varkw:
|
|
|
- raise Exception("do not support varargs")
|
|
|
- if not ('limit' in arg_names):
|
|
|
- raise Exception("function must has 'limit' in args")
|
|
|
- gen_key = gen_key_factory(key_pattern, arg_names, defaults)
|
|
|
- @wraps(f)
|
|
|
- def _(*a, **kw):
|
|
|
- key, args = gen_key(*a, **kw)
|
|
|
- start = args.pop('start', 0)
|
|
|
- limit = args.pop('limit')
|
|
|
- start = int(start)
|
|
|
- limit = int(limit)
|
|
|
- if not key or limit is None or start+limit > count:
|
|
|
- return f(*a, **kw)
|
|
|
- if isinstance(key, unicode):
|
|
|
- key = key.encode("utf8")
|
|
|
- r = mc.get(key)
|
|
|
-
|
|
|
- # anti miss-storm
|
|
|
- retry = max_retry
|
|
|
- while r is None and retry > 0:
|
|
|
- time.sleep(0.1)
|
|
|
- r = mc.get(key)
|
|
|
- retry -= 1
|
|
|
- r = pickle.loads(r) if r else None
|
|
|
-
|
|
|
- if r is None:
|
|
|
- r = f(limit=count, **args)
|
|
|
- mc.set(key, pickle.dumps(r), expire)
|
|
|
- return r[start:start+limit]
|
|
|
-
|
|
|
- _.original_function = f
|
|
|
- return _
|
|
|
- return deco
|
|
|
-
|
|
|
-def delete_cache_(key_pattern, mc):
|
|
|
- def deco(f):
|
|
|
- arg_names, varargs, varkw, defaults = inspect.getargspec(f)
|
|
|
- if varargs or varkw:
|
|
|
- raise Exception("do not support varargs")
|
|
|
- gen_key = gen_key_factory(key_pattern, arg_names, defaults)
|
|
|
- @wraps(f)
|
|
|
- def _(*a, **kw):
|
|
|
- key, args = gen_key(*a, **kw)
|
|
|
- r = f(*a, **kw)
|
|
|
- mc.delete(key)
|
|
|
- return r
|
|
|
- return _
|
|
|
- _.original_function = f
|
|
|
- return deco
|
|
|
-
|
|
|
-def create_decorators(mc):
|
|
|
-
|
|
|
- def _cache(key_pattern, expire=0, mc=mc, max_retry=0):
|
|
|
- return cache_(key_pattern, mc, expire=expire, max_retry=max_retry)
|
|
|
-
|
|
|
- def _pcache(key_pattern, count=300, expire=0, max_retry=0):
|
|
|
- return pcache_(key_pattern, mc, count=count, expire=expire, max_retry=max_retry)
|
|
|
-
|
|
|
- def _delete_cache(key_pattern):
|
|
|
- return delete_cache_(key_pattern, mc=mc)
|
|
|
-
|
|
|
- return dict(cache=_cache, pcache=_pcache, delete_cache=_delete_cache)
|
|
|
-
|
|
|
-
|
|
|
-globals().update(create_decorators(mc))
|
|
|
-
|