web.py——session

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/liyh_xd/article/details/78950633

使用web.py过程中,遇到两个疑问:

1、web.py如何管理相对自动的管理session?

2、session缓存的更新为何会有延迟?


通过学习web.py框架中session相关源码,有了答案:

1、web.py通过Session实例作为公共的session使用接口,Session实例基于threading模块提供线程安全的空间用于加载session,加载session依赖sessionID,sessionID-session字典序列化后存储于磁盘等位置。相同终端发起不同请求,通过不同线程到达应用程序,携带相同sessionID,加载相同session,因此拥有相同上下文环境。

2、session被加载至Session实例后可以被修改,用户请求处理完毕后更新至session缓存,因此更新存在延迟。另外,session更新基于覆盖机制,而不是合并机制。


以下为具体学习记录:


一、session生命周期
1、应用启动时,声明Application实例,声明Session实例(同时将session处理器添加至Application处理器队列),添加Session实例存储处理器。
2、请求到达时,依次调用前置应用处理器、请求处理方法、后置应用处理器。为确保Session实例全局可见,Session实例存储处理器必须为前置应用处理器,且存储位置必须全局可见。session处理器需完成事前加载、事后更新等工作,通过try...finally...语句同时实现前置应用处理器和后置应用处理器。
3、Session实例存储处理器也是前置应用处理器之一,为了Session实例全局可见,需要将Session实例存储处理器添加至一级应用的处理器队列中,并选择全局可见的位置存储Session实例,如web.ctx.session
4、session处理器的前置部分,包含清理过期session、加载session和session超时处理,出现session超时且不忽略时,将触发SessionExpired异常并将记录sessionID的cookie设置为超时
5、session处理器的后置部分,更新session缓存。因session更新存在延迟,延迟期间加载相同session并不能获得最新session。更新session缓存采取覆盖机制。

二、DiskStore类
DiskStore类用于根据sessionID对session进行增删改查
1、__init__(self, root)
初始化方法。root参数为session缓存根目录,确保根目录存在。
2、_get_path(key)
session文件路径生成方法。根据key和self.root生成session文件路径
3、__contain__(self, key)
in操作符的魔法方法。判断key对应的session是否已经存在,不考虑是否过期
4、__getitem__(self, key)/__setitem__(self, key, value)/__delitem__(key)
模拟字典操作的魔法方法。查询、更新、删除session,不考虑是否过期
5、cleanup(self, timeout)
删除过期session。遍历根目录下全部session,删除过期session
6、encode(self, session_dict)/decode(self, session_data)
session数据序列化和反序列化方法,以便可以通过文件存储session,继承自父类Store。

三、Session类
提供线程安全的空间加载session;提供Web框架中管理session需要的方法
1、__init__(self, app, store, initializer=None)
初始化方法。设置session相关配置,向app添加加载session的处理器。
Session设置了__slots__属性、提供线程安全变量空间的_data属性、重写了字典操作符相关魔法方法,将session在Session实例中的管理和存储分离开。
为了实现加载一次session整个Web框架可用的目的,加载session的处理器应该添加至一级应用的处理器列表中,得到的Session实例也应该保存至整个Web框架均可以访问的位置,如web.ctx.session
2、__contain__(self, key)
in操作符的魔法方法。判断key是否存在于session中
3、__getattr__(self, key)/__setattr__(self, key, value)/__delattr__(self, key)
点操作符的魔法方法。使Session实例支持通过点操作符访问session中的具体内容,__setattr__(self, key, value)方法也支持对Session实例的属性进行操作,Session实例和session出现同名键值对时,优先处理Session实例
4、_processor(self, handler)
应用处理器。用于在用户请求被具体处理前加载session,用户请求处理完毕后更新session。通过try...finally...关键字组,在一个应用处理器内实现了用户请求处理前后两次处理。
5、_cleanup(self)
过期session清理方法,应用处理器的一部分。调用self.store实例的cleanup(timeout)方法,清理过期session。
6、_load(self)
session加载方法,应用处理器的一部分。若用户请求携带了sessionID、sessionID格式合法、sessionID未过期,将读取sessionID代表的session,并更新self._data
session不存在或格式不合法或已过期,将重新生成sessionID,并根据self._initializer更新self._data,self._initializer应该为dict类型或自动更新self._data的可调用对象
session过期且Session实例设置为不忽略过期行为,将触发SessionExpired异常并在用户请求响应中设置记录sessionID的cookie项为过期状态
session存在且请求IP变化且Session实例设置为不忽略IP变化行为,将触发SessionExpired异常并在用户请求响应中设置记录sessionID的cookie项为过期状态
7、_check_expiry(self)
检测session是否过期,在self._load()方法中被调用,self._load()方法在self._cleanup()后调用。基于key in self.store判断。
session过期且Session实例设置为不忽略过期行为,将调用self.expired()方法进行session过期处理。
8、_validate_ip(self)
检测请求IP是否变化,在self._load()方法中被调用,确定session存在后被调用。
session存在且请求IP变化且Session实例设置为不忽略IP变化行为,将调用self.expired()方法进行session过期处理。
9、expired(self)
session过期处理方法。设置self._killed属性为True,表示session已过期;直接调用self._save()方法进行session更新相关操作;触发SessionExpired异常。
10、_save(self)
session和sessionID更新方法。通过self.store[sessionID] = self._data更新session缓存,通过设置响应头更新记录sessionID的cookie
11、_setcookie(self, session_id, expires='', **kw)
记录sessionID的cookie更新方法。
12、_generate_session_id(self)
sessionID生成方法。生成的sessionID要判断是否正在被使用。
13、kill(self)
session删除方法。del self.store[sessionID],且设置self._killed为True,以便self._save()方法进行相应处理

展开阅读全文

没有更多推荐了,返回首页