プロセスを介してユーザの要求の07フラスコソースコード解析

ユーザーの要求が来るプロセス: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は、すべての機能を実行し、すべての機能を見ます

  1. Full_dispatch_request機能の実行
  2. before_requestのすべての機能を実行します
  3. ビュー機能の実行
  • ソースコードの例:

    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)

おすすめ

転載: www.cnblogs.com/liubing8/p/11930727.html