【Flask源码分析——请求上下文与应用上下文】
Flask中有两种上下文,请求上下文和应用上下文。两者的作用域都处于一个请求的局部中。
查看源代码,上下文类在flask.ctx模块中定义
AppContext类定义应用上下文,app是当前应用Web对象的引用,g是当前请求内全局变量,每个请求的g都是独立的,在整个请求内都是全局可访问修改的。
RequestContext类定义请求上下文,request、session是所熟悉的经常用到的,app涵义和AppContext中相同。 上下文对象的作用域:
先说结论:请求上下文和应用上下文一样,他们的作用域是当前请求内,在当前请求内全局可访问。 线程中用ThreadLocal类实现线程间的隔离。同样的,werkzeug实现了自己的线程隔离类werkzeug.local.Local,看下图Flask处理一个请求的中间过程
LocalStack类是flask定义的用于线程隔离的栈存储对象,_app_ctx_stack和_request_ctx_stack由LocalStack类定义,分别用来保存应用和请求上下文。
(线程隔离:每个线程只能看到自己的结果,对于不同的线程,它们访问这两个对象看到的结果是不一样的、完全隔离的。这是根据线程pid的不同实现的。)
他们的定义在flask.globals模块中:
其中也定义了current,session等常用请求内全局对象,他们用LocalProxy定义,LocalProxy类的构造函数接收一个callable参数,上面这几个就传入了一个偏函数。以g为例,当对g进行操作时,就会调用作为参数的偏函数,并把操作转发到偏函数返回的对象上。
例如g对象的调用过程:
- 从当前线程应用上下文栈顶获取应用上下文
- 取出其中的g对象
- 进行操作
由图中flask处理请求的过程可知,客户端发起请求,创建了应用请求上下文并且推送到对应栈内,待flask server处理完成返回响应给客户端前,从栈中把当前请求的应用请求上下文删除掉,再返回响应给客户端就完成了一次完整的请求处理过程。
又因为每个应用里线程同时只处理一个请求,故上请求、应用下文栈肯定只有一个对象。并且,在请求结束后都会释放,所以新的请求来的时候都会重新推送两个上下文。
上下文的推送
Flask对象调用run()作为WSGI 应用启动后,每当有请求进入时,Flask调用push函数推送请求上下文
来看RequestContext类源码,push函数:
在推送请求上下文之前必须有应用上下文,Flask会检查当前线程的应用上下文栈顶是否有应用上下文:
- 如果有,判断与请求上下文是否属于同一个应用,(在单WSGI应用的程序中无意义,因为只创建一个app)
- 如果没有,就会推送一个当前应用的上下文,并记录下来。
请求处理结束,调用auto_pop函数,其中又调用自身的pop函数:
在pop函数中会把请求上下文和应用上下文都pop掉。
应用上下文AppContext源码,push,pop函数:
所以,在每个WSGI应用里,每个请求的两个上下文都是完全独立的,每次请求到来的时候都会推送请求上下文和应用上下文。如果应用上下文不存在,则会隐式的创建。
那么还有两个问题:
①应用和请求上下文在运行时都是线程隔离的,为何要分开来?
②每个线程同时只处理一个请求,上下文栈肯定只有一个对象,为何要用栈来存储?
参考其他资料后得出:这两个设计都是为了在离线状态下调试用。 下图是一位前辈的总结
小结:
对于flask编程来说,只有一个应用上的结论:每个请求的g都是独立的,并且在整个请求内都是全局可访问修改的。
所以,在每个WSGI应用里,每个请求的两个上下文都是完全独立的,每次请求到来的时候都会推送请求上下文和应用上下文。如果应用上下文不存在,则会隐式的创建。
【Flask源码分析——请求上下文与应用上下文】的更多相关文章
- flask源码分析
本flask源码分析不间断更新 而且我分析的源码全是我个人觉得是很beautiful的 1 flask-login 1.1 flask.ext.login.login_required(func),下 ...
- Flask源码分析二:路由内部实现原理
前言 Flask是目前为止我最喜欢的一个Python Web框架了,为了更好的掌握其内部实现机制,这两天准备学习下Flask的源码,将由浅入深跟大家分享下,其中Flask版本为1.1.1. 上次了解了 ...
- 浅谈flask源码之请求过程
更新时间:2018年07月26日 09:51:36 作者:Dear. 我要评论 这篇文章主要介绍了浅谈flask源码之请求过程,小编觉得挺不错的,现在分享给大家,也给大家做个参考.一起跟随 ...
- Tomcat源码分析——请求原理分析(下)
前言 本文继续讲解TOMCAT的请求原理分析,建议朋友们阅读本文时首先阅读过<TOMCAT源码分析——请求原理分析(上)>和<TOMCAT源码分析——请求原理分析(中)>.在& ...
- Tomcat源码分析——请求原理分析(中)
前言 在<TOMCAT源码分析——请求原理分析(上)>一文中已经介绍了关于Tomcat7.0处理请求前作的初始化和准备工作,请读者在阅读本文前确保掌握<TOMCAT源码分析——请求原 ...
- Tomcat源码分析——请求原理分析(上)
前言 谈起Tomcat的诞生,最早可以追溯到1995年.近20年来,Tomcat始终是使用最广泛的Web服务器,由于其使用Java语言开发,所以广为Java程序员所熟悉.很多人早期的J2EE项目,由程 ...
- flask源码剖析--请求流程
想了解这篇里面的内容,请先去了解我另外一篇博客Flask上下文 在了解flask之前,我们需要了解两个小知识点 偏函数 import functools def func(a1,a2): print( ...
- Flask源码分析一:服务启动
前言: Flask是目前为止我最喜欢的一个Python Web框架了,为了更好的掌握其内部实现机制,这两天准备学习下Flask的源码,将由浅入深跟大家分享下,其中Flask版本为1.1.1. Flas ...
- django源码分析 请求流程
一.从浏览器发出一个请求,到返回响应内容,这个过程是怎么样的? 1. 浏览器解析输入的url 2. 查找url对应的ip地址 3. 通过ip地址访问我们的服务器 1. 请求进入wsgi服务器(我在这 ...
随机推荐
- JavaScript创建对象的几种方式总结
ECMA把对象定义为:无序属性的集合,其属性可以包含基本值.对象或者函数. 1. 使用Object构造函数创建对象 创建自定义对象的最简单的方式就是创建一个Object的实例,然后再为它添加属性和方法 ...
- PHP的安全性问题,你能说得上几个?
一.SQL注入 所谓SQL注入,就是通过把SQL命令插入到Web表单提交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令.具体来说,它是利用现有应用程序,将(恶意)的SQL命令 ...
- paip.前端载入时间分析之道优化最佳实践
paip.前端载入时间分析之道优化最佳实践 1.另存为 ,查看文件尺寸..和图片. 2.view the 另存为的htm静态的文件单个的载入,看时间...能够排除编程语言的问题and 数据库.. ## ...
- Java 8最快的垃圾收集器是什么?
OpenJDK 8 有多种 GC(Garbage Collector)算法,如 Parallel GC.CMS 和 G1.哪一个才是最快的呢?如果在 Java 9 中将 Java 8 默认的 GC 从 ...
- 关于本地文件请求json文件
因为需要用到json数据格式,上网查了一下例子之后我就想本地测试一下看能不能成功. 结果,chrome下没有任何反应,打开控制台之后报错如下: XMLHttpRequest cannot load f ...
- androidstudio如何用github多人开发
一.首先我们利用github作为代码库,有两种方法可以创建代码库 一定要配置好git环境和创建好github账号 检测git环境配置 检测github账号是否能登录 成功就会 (1)在github中直 ...
- IntelliJ IDEA 下的svn配置及使用的非常详细的图文总结(转)
IntelliJ IDEA使用教程 (总目录篇) 首先,使用的时候,自己得先在电脑上安装个小乌龟.也就是svn啦. 第一步安装小乌龟. 如下: 具体安装好像没什么具体要求,一路next,就好. 如上图 ...
- phpcms推送文章同时推送自定义字段
首先进入phpcms后台,模型管理-字段管理里,新建字段,新建字段必须是主表字段,如图所示 2 来到网站根目录,寻找phpcms\modules\content\classes\push_api.cl ...
- Linux之rpm包管理-yum在线管理
1.IP地址配置 1.以root登录Linux系统,在终端输入setup启动图形界面menuconfing,如下图所示: 2.选择network configuration ,进入网络配置界面,进入后 ...
- JavaScript--函数对象的属性caller与callee
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...