python本地缓存

import datetime
import functools
import heapq
import inspect
import logging
import random
import time
import weakref

from eventlet.semaphore import Semaphore

from service.globaldef import Consts

logger = logging.getLogger(__name__)

def _argdict(f, args, kwargs):
    argnames, _args, _kwargs, defaults = inspect.getargspec(f)
    argdict = {}
    if defaults:
        k = len(argnames) - len(defaults)
        argdict.update(dict(zip(argnames[k:], defaults)))
    if args:
        argdict.update(dict(zip(argnames[:len(args)], args)))
    argdict.update(kwargs)
    if len(argdict) < len(argnames):
        raise Exception("require %d args, but get %d" %
                        (len(argnames), len(argdict)))
    return argdict


class CacheEntry(object):
    def __init__(self, end_ts=0, val=None):
        self.end_ts = end_ts
        self.val = val


class MyQueue(object):
    def __init__(self, maxsize=0):
        self.queue = []
        self.maxsize = maxsize
        self.semaphore = Semaphore()

    def append(self, priority, data):
        x = None
        with self.semaphore:
            if self.maxsize and len(self.queue) >= self.maxsize:
                x = heapq.heappop(self.queue)
            heapq.heappush(self.queue, (priority, data))
        print 'append: ', (priority, data), ',heappop:', x


class LocalCache(object):
    _CACHE = weakref.WeakValueDictionary()
    STRONG_REF = MyQueue(10000)
    NOT_FOUND = CacheEntry()

    @classmethod
    def get_key(cls, func, key_fmt, args, kwargs):
        if key_fmt is None:
            cache_key = "%s.%s.%s" % (
                Consts.SVR_NAME, func.__module__, func.__name__)
        else:
            arg_dict = _argdict(func, args, kwargs)
            cache_key = key_fmt.format(**arg_dict)
        return cache_key

    @classmethod
    def get_cache(cls, key):
        return cls._CACHE.get(key, cls.NOT_FOUND)

    @classmethod
    def set_cache(cls, key, val, expire):
        now = time.time()
        cache_entry = CacheEntry(now + expire, val)
        cls._CACHE[key] = cache_entry
        cls.STRONG_REF.append(cache_entry.end_ts, cache_entry)

    @classmethod
    def cacheable(cls, key_fmt=None, expire=30):
        """
        本地缓存 ,注意 key_fmt 如果 是 None 那么不会把 方法的参数作为 key
        :param key_fmt:  key 可添加动态参数
        :param expire: 单位 秒 缓存 多少秒
        :return:
        """

        def decorate(func):
            @functools.wraps(func)
            def wrapper(*args, **kwargs):
                cache_key = cls.get_key(func, key_fmt, args, kwargs)

                ts = time.time()
                cache_entry = cls.get_cache(cache_key)
                if ts <= cache_entry.end_ts:
                    logger.info('locacache hint,cache_key:%s' % cache_key)
                    return cache_entry.val
                else:
                    ret_val = func(*args, **kwargs)
                    cls.set_cache(cache_key, ret_val, expire)
                    return ret_val

            return wrapper

        return decorate


if __name__ == '__main__':
    x = MyQueue(2)
    for i in range(10):
        x.append(random.randint(0, 100), 'x')



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值