!/usr/bin/env python
-- coding: utf-8 --
"""智能缓存基类 适用于更新不频繁并且数据需要实时同步的情景"""
import abc
from django.conf import settings
from django.core.cache import cache
try:
import simplejson as json
except:
import json
class BaseSmartCache(object):
metaclass = abc.ABCMeta
def __init__(self, force_cache=False, force_source=False, smart=False,
*args, **kwargs):
"""智能缓存类
:param force_cache: 强制使用缓存的数据
:param force_source: 强制使用源数据
:param smart: 智能检查开关
"""
assert not all([force_cache, force_source]), \
('force_cache and force_source can not assign to True '
'at the same time')
self._force_cache = force_cache
self._force_source = force_source
self._smart = smart
self._data = None
self._cache_id = None
self._cache_key = None
self._client = self.client()
self._latest_update = None
def client(self):
return cache
def prepare(self):
pass
def fetch(self):
self.prepare()
if self._force_source or not settings.ENABLE_CACHE:
self._data = self.source()
else:
_cache = self.get()
self._data = _cache and _cache['value']
if not self._force_cache and (_cache is None or (
self._smart and _cache['id'] != self.cache_id)):
self.refresh()
return self.handle()
def handle(self):
return self.data
def pre_set(self):
pass
def set(self):
data = {'id': self.cache_id, 'value': self.data}
return self._client.set(self.cache_key, data, self.expires)
def get(self):
return self._client.get(self.cache_key)
def delete(self):
return self._client.delete(self.cache_key)
def refresh(self):
self._data = self.source()
self.pre_set()
self.set()
@property
def data(self):
return self._data
@property
def cache_key(self):
if not self._cache_key:
self._cache_key = self.get_cache_key()
return self._cache_key
@property
def cache_id(self):
if not self._cache_id:
self._cache_id = self.get_cache_id()
return self._cache_id
@abc.abstractproperty
def expires(self):
pass
@abc.abstractmethod
def get_cache_key(self):
pass
@abc.abstractmethod
def get_cache_id(self):
pass
@abc.abstractmethod
def source(self):
pass