Skip to content

Instantly share code, notes, and snippets.

@huaxinjiayou
Last active August 29, 2015 14:16
Show Gist options
  • Save huaxinjiayou/de157d68aca9b7373525 to your computer and use it in GitHub Desktop.
Save huaxinjiayou/de157d68aca9b7373525 to your computer and use it in GitHub Desktop.
tornado session 和 flash 实现,参考了 https://gist.github.com/ayang/1735032
# -*-coding:utf-8-*-
import tornado.web
from frame.region import region
from frame.region import Session
from frame.region import Flash
import services.user
class BaseRequestHandler(tornado.web.RequestHandler):
# 这个函数的返回值,会体现在模板的 current_user 中
def get_current_user(self):
uid = self.session['uid']
return services.user.find_by_id(uid) if uid else None
def logout(self):
self.session.clear()
def __init__(self, *argc, **argkw):
super(BaseRequestHandler, self).__init__(*argc, **argkw)
self.region = region
self.request.flash = self.flash.get()
@property
def session(self):
session_id = self.get_secure_cookie('sid')
session = Session(session_id)
if not session_id:
self.set_secure_cookie('sid', session.session_id)
return session
@property
def flash(self):
return Flash(self.session)
# -*-coding:utf-8-*-
from uuid import uuid4
from dogpile.cache import make_region
import config
region = make_region(
key_mangler=lambda key: 'ncms:tornado:' + key
).configure(
'dogpile.cache.redis',
arguments={
'host': config.redis['host'],
'port': config.redis['port'],
'db': config.redis['db'],
'distributed_lock': True
}
)
class Session(object):
# 缓存池,主要用于:
# A 页面 redict 到 B 页面,B 的 __init__ 比 A 的 __del__ 先执行,造成 session 数据不同步
pool = {}
def __init__(self, session_id=None):
self._session_id = session_id if session_id else uuid4().get_hex()
# 先从 redis 中读取,再从类池中读取,最后再新建
session_data = region.get(self._session_id)
if not session_data and self._session_id in Session.pool:
session_data = Session.pool[self._session_id]
self._session_data = session_data if session_data else dict()
Session.pool[self._session_id] = self._session_data
self.dirty = False
def clear(self):
region.delete(self._session_id)
@property
def session_id(self):
return self._session_id
def clear(self, key=None):
if key:
if key in self._session_data:
self.__delitem__(key)
return
region.delete(self._session_id)
if self._session_id in Session.pool:
del Session.pool[self._session_id]
self._session_data = dict()
Session.pool[self._session_id] = self._session_data
def __getitem__(self, key):
if key in self._session_data:
return self._session_data[key]
def __setitem__(self, key, value):
self._session_data[key] = value
self._dirty()
def __delitem__(self, key):
if key in self._session_data:
del self._session_data[key]
self._dirty()
def __len__(self):
return len(self._session_data)
def __contains__(self, key):
return key in self._session_data
def __iter__(self):
for key in self._session_data:
yield key
def __repr__(self):
return self._session_data.__repr__()
def __del__(self):
if self.dirty:
self._save()
if self._session_id in Session.pool:
del Session.pool[self._session_id]
def _dirty(self):
self.dirty = True
def _save(self):
region.set(self._session_id, self._session_data)
self.dirty = False
class Flash:
def __init__(self, session):
self.session = session
def set(self, key, value):
data = self.session['ncms.flash.data']
data = data if data else dict()
data[key] = value
self.session['ncms.flash.data'] = data
def get(self):
data = self.session['ncms.flash.data']
self.session.clear('ncms.flash.data')
return data if data else dict()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment