ユーザーの要求が来るプロセス:07フラスコソース
1.オブジェクトを作成します。CTX = RequestContextの
パッケージオブジェクト・リクエスト・オブジェクトRequestContextの
RequestContextのセッションオブジェクトは、データをカプセル化
ソースは達成します:
def wsgi_app(self, environ, start_response): """ ctx = RequestContext(self, environ) """ # 2.1 创建RequestContext对象 ctx = self.request_context(environ)
def request_context(self, environ): return RequestContext(self, environ)
request_class = Request class RequestContext(object): def __init__(self, app, environ, request=None, session=None): self.app = app if request is None: """ request_class = Request """ request = app.request_class(environ) self.request = request self.session = session
2.作成app_ctx = AppContextをオブジェクト
Appオブジェクトオブジェクトは、AppContextををカプセル化
AppContextをオブジェクトカプセル化グラム
ソースは達成します:
def wsgi_app(self, environ, start_response): """ ctx = RequestContext(self, environ) """ # 2.1 创建RequestContext对象 ctx = self.request_context(environ) error = None try: try: """ 2.2 执行ctx.push - app_ctx = 创建AppContext对象(app,g) - 将app_ctx放入local中 - 将ctx放入到local中 - session赋值 - 路由匹配 """ ctx.push()
def push(self): top = _request_ctx_stack.top if top is not None and top.preserved: top.pop(top._preserved_exc) app_ctx = _app_ctx_stack.top if app_ctx is None or app_ctx.app != self.app: """ app_ctx = AppContext(app) """ # 创建appcontext对象 app_ctx = self.app.app_context()
def app_context(self): return AppContext(self)
class AppContext(object): def __init__(self, app): self.app = app self.g = app.app_ctx_globals_class()
3. CTXオブジェクト、ローカルにapp_ctxオブジェクト
Ctx.pushは、[ローカルでそれらを配置するために、独自のLocalStackを通じて、CTXオブジェクトがトリガされます
その後app_ctx.pushトリガーは、ローカルにそれらを配置するための独自のLocalStackを通じて、オブジェクトをapp_ctxます
キーとしてスレッドIDの性質に基づいて、ローカルに{「スタック」:[]}辞書の値です。
ストレージ構造:{
1111:{ "スタック":[CTX、]}
}。{
1111:{「スタック」:[app_ctx、]}
}ソースコードの例:
def push(self): top = _request_ctx_stack.top if top is not None and top.preserved: top.pop(top._preserved_exc) app_ctx = _app_ctx_stack.top if app_ctx is None or app_ctx.app != self.app: """ app_ctx = AppContext(app) """ # 创建appcontext对象 app_ctx = self.app.app_context() # push将app_ctx放入到local中 app_ctx.push() self._implicit_app_ctx_stack.append(app_ctx) else: self._implicit_app_ctx_stack.append(None) if hasattr(sys, "exc_clear"): sys.exc_clear() """ self = ctx = RequestContext(self, environ) """ # push将ctx放入到local中 _request_ctx_stack.push(self) if self.session is None: session_interface = self.app.session_interface self.session = session_interface.open_session(self.app, self.request) if self.session is None: self.session = session_interface.make_null_session(self.app) if self.url_adapter is not None: # 路由匹配,将匹配到的endpoint放到request.url_rule中 self.match_request()
4. before_requestは、すべての機能を実行し、すべての機能を見ます
- Full_dispatch_request機能の実行
- before_requestのすべての機能を実行します
- ビュー機能の実行
ソースコードの例:
def wsgi_app(self, environ, start_response): """ ctx = RequestContext(self, environ) """ #2.1 创建RequestContext对象 ctx = self.request_context(environ) error = None try: try: # 做了很多事 """ 2.2 执行ctx.push - app_ctx = 创建AppContext对象(app,g) - 将app_ctx放入local中 - 将ctx放入到local中 - session赋值 - 路由匹配 """ ctx.push() # 2.3 执行before_request/视图/after_request (处理session) response = self.full_dispatch_request()
def full_dispatch_request(self): # 触发所有的before_first_request_funcs函数 # 只在启动程序后,第一个请求到来时执行 self.try_trigger_before_first_request_functions() try: # 信号,暂留 request_started.send(self) # 执行before_request_funcs函数,如果有返回值就不执行视图函数了 rv = self.preprocess_request() if rv is None: # 执行视图函数 rv = self.dispatch_request() except Exception as e: rv = self.handle_user_exception(e) # 视图函数执行之后 # 1.执行所有的after_request # 2.保存session return self.finalize_request(rv)
すべての機能の実装after_request
セッションの暗号化には、クッキーの中に、ユーザーのブラウザに返されます
ソースコードの例:
def finalize_request(self, rv, from_error_handler=False): # 将rv视图函数返回值,封装到Reponse对象中 response = self.make_response(rv) response = self.process_response(response) return response
response_class = Response def make_response(self, rv): if not isinstance(rv, self.response_class): if isinstance(rv, (text_type, bytes, bytearray)): rv = self.response_class(rv, status=status, headers=headers) return rv
def process_response(self, response): ctx = _request_ctx_stack.top funcs = ctx._after_request_functions # 执行所有的after_request_funcs funcs = chain(funcs, reversed(self.after_request_funcs[None])) for handler in funcs: response = handler(response) if not self.session_interface.is_null_session(ctx.session): # 保存session self.session_interface.save_session(self, ctx.session, response) return response
6. CTX破壊とapp_ctx
要求が破壊とapp_ctx CTXの終わりではない場合、その後、メモリリークになり
ポップメソッドの呼び出しCTXとapp_ctx
ソースコードの例:
def wsgi_app(self, environ, start_response): """ ctx = RequestContext(self, environ) """ #2.1 创建RequestContext对象 ctx = self.request_context(environ) error = None try: try: """ 2.2 执行ctx.push - app_ctx = 创建AppContext对象(app,g) - 将app_ctx放入local中 - 将ctx放入到local中 - session赋值 - 路由匹配 """ ctx.push() # 2.3 执行before_request/视图/after_request (处理session) response = self.full_dispatch_request() except Exception as e: error = e response = self.handle_exception(e) except: # noqa: B001 error = sys.exc_info()[1] raise return response(environ, start_response) finally: if self.should_ignore_error(error): error = None # 2.4 销毁ctx/app_ctx ctx.auto_pop(error)
def auto_pop(self, exc): self.pop(exc)
def pop(self, exc=_sentinel): app_ctx = self._implicit_app_ctx_stack.pop() finally: rv = _request_ctx_stack.pop() if app_ctx is not None: app_ctx.pop(exc)