执行app对象中的after_request_funcs列表的所有方法,以构建的Response对象作为参数,每个方法必须都返回Response类型的对象,最后调用session保存本次的状态信息;
第四步:出栈先执行app对象的teardown_request_funcs列表中的所有的方法,其方法和after_request_funcs中的一样,只不过是在出栈前才触发,这意味着即使处理逻辑的部分出错,这里方法也会执行,然后从_request_ctx_stack中弹出RequestContext请求上下文,然后执行app对象中的teardown_appcontext_funcs列表的所有方法,最后从_app_ctx_stack中弹出AppContext应用上下文。
class AppContext: def pop(self, exc=_sentinel): app_ctx = self._implicit_app_ctx_stack.pop() try: clear_request = False if not self._implicit_app_ctx_stack: self.preserved = False self._preserved_exc = None if exc is _sentinel: exc = sys.exc_info()[1] self.app.do_teardown_request(exc) # 调用请求钩子 if hasattr(sys, 'exc_clear'): sys.exc_clear() request_close = getattr(self.request, 'close', None) if request_close is not None: request_close() clear_request = True finally: rv = _request_ctx_stack.pop() # 弹出请求上下文 if clear_request: rv.request.environ['werkzeug.request'] = None if app_ctx is not None: app_ctx.pop(exc) # 弹出应用上下文 flask请求处理最简代码模型假设服务器使用的是多进程模式。
from multiprocessing import Process, Pool class Flask(object): def __call__(self, environ, start_response): """定义app对请求的处理过程""" pass def listen_port(): """假设这是端口监听并解析http请求的方法""" pass def run_web(): """假设这是程序主循环""" app = Flask() # 创建一个app,这是app初始化做的 pool = Pool(10) while True: # 获取一个http请求的数据 environ, start_response = listen_port() # 调用app处理请求 pool.apply_async(app, args=(environ, start_response)) if __name__ == '__main__': run_web() 总结无论是gunicorn服务器还是uwsgi服务器,其启动后加载了app对象;
当收到http请求后,按照http协议解析数据,将数据打包成一个字典,将其和响应函数一起作为参数调用app对象的wsgi_app方法;
wsgi_app方法按照接收请求,创建上下文,入栈,请求分发,出栈的步骤处理完业务逻辑返回响应数据;
参考https://dormousehole.readthedocs.io/en/latest/