2011/09/22

Implement tornado session in memcached

示範將tornado的session實作在memcached裡面,我是參考這個blog:
玩蛇记-给tornado加上session支持 - 亚历山大同志 - 博客园

Requirement
  • Tornado 2.0
  • python-libmemcached 0.4
    • Pyrex 0.9.4+
    • libmemcached 0.52

邏輯


流程



直接來看code
這是一個可以用在user登入的sample
import tornado.ioloop
import tornado.web
import tornado.options
import cmemcached
import ast
import datetime


from tornado.options import define, options
define("expiration", default = (60 * 60 * 24), help = "session expiration time")

class session_imple():
    def __init__(self, key = None):
        global mmc
        self.key = key
        pack = mmc.get(self.key)
        if pack:
            self.status = True
            print pack
            self.dict = ast.literal_eval(pack)
            return
        
        # session not exist or expire
        self.status = False
        
    def __getitem__(self, tag):
        return self.dict[tag]
    
    def __setitem__(self, tag, value):
        self.dict[tag] = value
        
    def writeback(self):
        global mmc
        pack = str(self.dict)
        mmc.set(self.key, pack, options.expiration)
        
def session(method):
    def wrapper(self, *args, **kwargs):
        if not self.current_user:
            self.redirect(self.get_login_url())
            return
        
        self.session = session_imple(self.current_user)
        # check session status
        if not self.session.status:
            self.clear_cookie("session_key")
            self.redirect(self.get_login_url())
            return
        
        method(self, *args, **kwargs)
        self.session.writeback()
    return wrapper

class BaseHandler(tornado.web.RequestHandler):
    def get_current_user(self):
        return self.get_secure_cookie("session_key")

class MainHandler(BaseHandler):
    @session
    def get(self):
        # Access the session
        name = self.session["name"]
        self.session["last_access"] = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
        self.write("Hello, " + name + ". " + 
                   "logout")

class LoginHandler(BaseHandler):
    def get(self):
        self.write('
' 'Name: ' '' '
') def post(self): ''' TODO: authenticate the user by your way. ''' # If the user pass the authentication, store the session key in the memcached name = self.get_argument("name") session_key = "KEY:" + name global mmc mmc.set(session_key, str( {"name": name } ), options.expiration) self.set_secure_cookie("session_key", session_key) self.redirect("/") class LogoutHandler(BaseHandler): def get(self): self.clear_cookie("session_key") self.redirect("/") settings = dict( debug = True, cookie_secret = "459eb8ae005b152640eef3d83a0b31a6", login_url = "/login", ) application = tornado.web.Application([ (r"/", MainHandler), (r"/login", LoginHandler), (r"/logout", LogoutHandler) ], **settings) if __name__ == "__main__": tornado.options.parse_command_line() mmc = cmemcached.Client(["localhost:11211"]) application.listen(8888) tornado.ioloop.IOLoop.instance().start()


參考資料


沒有留言:

張貼留言