class Redis(CacheBase, CacheMixIn): def __init__(self, timeout=300, **kwargs): self.storage_url = project.setting('cache', 'storage_url') try: self.engine = StorageEngineRedis(self.storage_url).get_engine() except StorageEngineError: raise super(Redis, self).__init__(timeout, **kwargs) def get(self, key, default=None): value = default now = time.time() data = self.engine.get(key) expire_data, value_data = data.split(':', 1) expire = pickle.loads(expire_data) if expire < now: self.delete(key) else: value = pickle.loads(value_data) return value def set(self, key, value, timeout=None): if not timeout: timeout = self.timeout self._cleanup() now = time.time() expire_data = pickle.dumps(now + timeout, pickle.HIGHEST_PROTOCOL) value_data = pickle.dumps(value, pickle.HIGHEST_PROTOCOL) self.engine.set(key, ':'.join(expire_data, value_data)) def delete(self, key): self.engine.delete(key) def contains(self, key): if self.engine.exists(key): now = time.time() data = self.engine.get(key) expire_data = data.split(':', 1)[0] expire = pickle.loads(expire_data) if expire < now: self.delete(key) return False else: return True else: return False def clear(self): self.engine.flushdb() def _cleanup(self): for key in self.engine.keys('*'): data = self.engine.get(key) expire_data = data.split(':', 1)[0] expire = pickle.loads(expire_data) now = time.time() if expire < now: self.engine.delete(key)
class SessionStoreRedis(SessionStore): """ Session storage in Redis key-value store. 'session_id': '[atime]:[data]' """ def __init__(self, storage_url=None, **kw): super(SessionStoreRedis, self).__init__(storage_url=storage_url) try: self.engine = StorageEngineRedis(self.storage_url).get_engine() except: raise SessionStoreError("Could not create connection " "for: %s " % self.storage_url) def __contains__(self, key): return self.engine.exists(key) == 1 def __getitem__(self, key): now = int(time.mktime(datetime.datetime.utcnow().timetuple())) if self.engine.exists(key) == 1: try: value = self.engine.get(key) atime, data = value.split(':') new_value = ':'.join((str(now), data)) self.engine.set(key, new_value) try: self.engine.bgsave() except redis.ResponseError: pass return self.decode(data) except: raise KeyError else: raise KeyError def __setitem__(self, key, value): now = int(time.mktime(datetime.datetime.utcnow().timetuple())) pickled = self.encode(value) redis_value = ':'.join((str(now), pickled)) self.engine.set(key, redis_value) try: self.engine.bgsave() except redis.ResponseError: pass def __delitem__(self, key): self.engine.delete(key) try: self.engine.bgsave() except redis.ResponseError: pass def cleanup(self, timeout): timeout = datetime.timedelta(timeout/(24.0*60*60)) last_allowed_time = datetime.datetime.utcnow() - timeout last_allowed_timestamp = int(time.mktime(last_allowed_time.timetuple())) for key in self.engine.keys('*'): value = self.engine.get(key) #atime = int(value.split(':')[0]) atime = int(float(value.split(':')[0])) if atime < last_allowed_timestamp: self.engine.delete(key)