• Tornado 高并发源码分析之三--- Application 对象


    Application 对象主要工作:
    服务器启动时:
    1、在新建一个app的时候,根据设置好的 URL 和回调函数 Handler 封装成URLSpec 对象
     
    服务器运行时:
    2、在请求到来,将 HTTPServer 封装好的HTTPRequest 传入_RequestDispatcher对象,_RequestDispatcher对象根据传入的 HTTPRequest 使用URLSpec解析匹 match 正则匹配找到对应的 RequestHandler ,执行它的 _execute 方法
     
    Application设计优点
    1、Application 本身不处理数据,只是封装 URL , 解析请求的 URL, 分发到 URL 相对应的 RequestHandler 去执行具体操作
     
    以下为源码分析,省略了一部分代码,只取关键部分显示
     1 class Application(httputil.HTTPServerConnectionDelegate):   
     2 # 继承自httputil.HTTPServerConnectionDelegate, 其实HTTPServerConnectionDelegate只是一种类似于协议的东西,只要继承自他就可以了,方便其他地方可以调用 isinstanct 来判断,
     3 def __init__(self, handlers=None, default_host="", transforms=None, **settings):
     4 #完成 url映射 和 setting相关的设置
     5 
     6     self.handlers = []
     7     self.named_handlers = {}  
     8     self.settings = settings   #导入设置的参数
     9 
    10     if handlers:
    11         self.add_handlers(".*$", handlers)     #将URL 和 Handler 映射封装成 URLSpec 对象
    12 
    13     if self.settings.get('autoreload'):   #设置自动重启
    14         from tornado import autoreload
    15         autoreload.start()
    16 
    17 
    18 def add_handlers(self, host_pattern, host_handlers):
    19          #将 url 和 handler 封装成URLSpec
    20     for spec in host_handlers:
    21         if isinstance(spec, (tuple, list)):
    22             assert len(spec) in (2, 3, 4)
    23             spec = URLSpec(*spec)   #封装成 URLSpec 对象
    24         handlers.append(spec)   
    25         if spec.name:
    26             if spec.name in self.named_handlers:
    27                 app_log.warning(
    28                     "Multiple handlers named %s; replacing previous value",
    29                     spec.name)
    30             self.named_handlers[spec.name] = spec   #将url 和 handler隐射封装起来
    31 
    32 def __call__(self, request):
    33     # 在这里巧用了__call__方法,当一个application 新建的时候,将会被动调用,这个是在请求信息已经接收完毕,已经封装成 HTTPRequest 对象之后,执行用户的 RequestHandler 对象的get、post方法
    34     dispatcher = _RequestDispatcher(self, None)
    35     dispatcher.set_request(request)   #将封装好的HTTPRequest对象(此时数据已经接收完毕),设置进_RequestDispatcher中,
    36     return dispatcher.execute()  #执行用户的 RequestHandler 对象的get、post方法,对数据处理,并返回
     1 class _RequestDispatcher(httputil.HTTPMessageDelegate):
     2 正在用来执行用户写的 RequestHandler 对象里面的get、post等方法
     3 def set_request(self, request):
     4     self.request = request  #设置request
     5     self._find_handler()   #根据request查找url匹配
     6     self.stream_request_body = _has_stream_request_body(self.handler_class)
     7 
     8 def _find_handler(self):
     9 #
    10     app = self.application
    11     handlers = app._get_host_handlers(self.request)   #从request中获取头信息
    12     if not handlers:
    13         self.handler_class = RedirectHandler
    14         self.handler_kwargs = dict(url="http://" + app.default_host + "/")
    15         return
    16     for spec in handlers:  #遍历url 匹配的类
    17         match = spec.regex.match(self.request.path)  #url路径匹配
    18         if match:
    19             self.handler_class = spec.handler_class  #获取url匹配的我们写的自定义的RequestHandler类
    20             self.handler_kwargs = spec.kwargs
    21             if spec.regex.groups:
    22                 if spec.regex.groupindex:
    23                     self.path_kwargs = dict(
    24                         (str(k), _unquote_or_none(v))
    25                         for (k, v) in match.groupdict().items())
    26                 else:
    27                     self.path_args = [_unquote_or_none(s)
    28                                       for s in match.groups()]
    29             return
    30 
    31 
    32 def execute(self):
    33     self.handler = self.handler_class(self.application, self.request, **self.handler_kwargs)   #获取我们自定义的RequestHandler类实例,传递参数
    34 
    35     if self.stream_request_body:   #先创建一个future 对象
    36         self.handler._prepared_future = Future()
    37 
    38     self.handler._execute(transforms, *self.path_args, **self.path_kwargs)   #执行我们自定义的,继承RequestHandler类的 _execute 函数, 所以最后我们的写的get post方法,还是在自己的那个类的_execute方法中调用执行的
    39 
    40     return self.handler._prepared_future   #返回自定义的RequestHandler future 对象
  • 相关阅读:
    用于Delphi的DevExpress VCL组件——富文本编辑功能升级
    5个技巧,教你优化React App性能
    DevExpress WPF模板库助力快速完成界面美化
    Web开发小技巧放送
    WinForm应用界面开发入门指南
    浅析C#中单点登录的原理和使用
    Wireshark抓包,带你快速入门
    你必须知道的EF知识和经验
    你知道SqlDataAdapter中的Fill是怎么实现的吗
    一文说通C#中的异步编程
  • 原文地址:https://www.cnblogs.com/hepingqingfeng/p/6655708.html
Copyright © 2020-2023  润新知