zoukankan      html  css  js  c++  java
  • 上下文管理

    请求上下文管理流程:

    - 请求到来之后wsgi会触发__call__方法,由__call__方法再次调用wsgi_app方法
    - 在wsgi_app方法中:
        - 首先将 请求相关+空session 封装到一个RequestContext对象中,即:ctx。
        - 将ctx交给LocalStack对象,再由LocalStack将ctx添加到Local中,Local结构:
            __storage__ = {
                1231:{stack:[ctx,] }
            }
        - 根据请求中的cookie中 提取 名称为sessionid对应的值,对cookie进行加密+反序列化,再次赋值给ctx中的session
        
        -> 执行视图函数
        
        - 把session中的数据再次写入到cookie中。
        - 将ctx删除
    - 结果返回给用户浏览器
    - 断开socket连接

    概要

    # 1 请求到来时候:
    # ctx = RequestContext(self, environ) # self是app对象,environ请求相关的原始数据
        # ctx.request = Request(environ)
        # ctx.session = None
    
    # 将包含了request/session的ctx对象放到“空调”
    {
        1232:{ctx: ctx对象}
      1231:{ctx: ctx对象}
      1211:{ctx: ctx对象}
      1111:{ctx: ctx对象}
      1261:{ctx: ctx对象}
    }
    
    # 2 视图函数获取request/session:
        #视图函数在获取request / session时,内部隐含的操作是根据当前线程 / 协程的唯一标识取到ctx对象,再去ctx对象取request / session
        # 方式一:直接找LocalStack获取
             from flask.globals import _request_ctx_stack.top
            print(_request_cxt_stack.top.request.method)
        # 方式二:通过代理LocalProxy获取
                from flask import Flask,request
                print(request.method)
    
    # 3 请求结束:
    # 根据当前线程的唯一标记,将“空调”上的数据移除。

    一  flask请求上下文管理流程图 

       三、请求上下文和app上下文:

    - 请求上下文(ctx=RequestContext()):request/session
    -  App上下文(app_ctx=AppContext()): app/g
        
    - 程序启动:
        两个Local:
            local1 = {
            
            }
            
            local2 = {
            
            }
    
        两个LocalStack:
            _request_ctx_stack
            _app_ctx_stack
    - 请求到来
        对数据进行封装:
            ctx = RequestContext(request,session)
            app_ctx = AppContext(app,g)
        保存数据:
            将包含了(app,g)数据的app_ctx对象,利用 _app_ctx_stack(LocalStack())将app_ctx添加到Local中
                storage = {
                    1231:{stack:[app_ctx(app,g),]}
                }
            将包含了request,session数据的ctx对象,利用_request_ctx_stack(刘淞,LocalStack()),将ctx添加到Local中
                storage = {
                    1231:{stack:[ctx(request,session),]}
                }
                
    - 视图函数处理:   
        
        from flask import Flask,request,session,current_app,g
    
        app = Flask(__name__)
        @app.route('/index')
        def index():
            # 去请求上下文中获取值 _request_ctx_stack
            request.method # 找小东北获取值
            session['xxx'] # 找龙泰获取值
            
            # 去app上下文中获取值:_app_ctx_stack 
            print(current_app)
            print(g)        
            return "Index"
    
        if __name__ == '__main__':
            app.run()
            app.wsgi_app
    
    - 结束
        _app_ctx_stack.pop()
        _request_ctx_stack.pop()

     问题:

    1. Flask中g的生命周期?
            当每次请求进来的时候,会为每个请求创建一个g,在请求结束的时候g被移出;
            也就是说g只存在与当前请求的生命周期内
        
        2. g和session一样吗?
            不一样,g在请求结束的时候被清除了;session在请求结束的时候写入cookie中,请求来的时候可以从cookie中进行读取
        3. g和全局变量一样吗?
        
            不一样:
            全局变量在项目启动的时候被创建,g在请求来的时候被创建
            多线程,多线程来的时候操作全局变量会有问题,但g放在Local中,Local根据线程的唯一标识进行拆分开了
            全局变量设置完后会存放在内存中,没有被销毁,下次来还能读,而g被删掉了
        
        4.g的使用场景
            一次http请求内,如果先做一次操作再后做一个操作,后一个操作需要前面给它设置一些值的时候可以用到g

     二 flask-session  

    pip3 install flask-session

    1、使用

    import redis
    from flask import Flask,sessionfrom flask_session import Session
    
    app = Flask(__name__)
    
    app.config['SESSION_TYPE'] = 'redis'
    app.config['SESSION_REDIS'] = redis.Redis(host='140.143.227.206',port=6379,password='1234')
    Session(app)
    
    @app.route('/login')
    def login():
        session['user'] = 'alex'
        return 'asdfasfd'
    
    @app.route('/home')
    def index():
        print(session.get('user'))
    
        return '...'
    
    
    if __name__ == '__main__':
        app.run()

    2、原理

    - session数据保存到redis
        session:随机字符串1:q23asifaksdfkajsdfasdf
        session:随机字符串2:q23asifaksdfkajsdfasdf
        session:随机字符串3:q23asifaksdfkajsdfasdf
        session:随机字符串4:q23asifaksdfkajsdfasdf
        session:随机字符串5:q23asifaksdfkajsdfasdf
    - 随机字符串返回给用户。
        随机字符串
    
    
    源码:
        from flask_session import RedisSessionInterface
  • 相关阅读:
    java面试之String源码中equals具体实现
    JVM虚拟机—JVM的垃圾回收机制(转载)
    Mysql学习笔记—视图
    Mysql学习笔记—索引
    JVM虚拟机—JVM内存
    设计模式—装饰器模式
    设计模式—代理模式
    设计模式—适配器模式
    设计模式—观察者模式
    设计模式—建造者模式
  • 原文地址:https://www.cnblogs.com/zh-xiaoyuan/p/13232651.html
Copyright © 2011-2022 走看看