quart源码阅读(一)

def run(
            self,host: str='127.0.0.1',port: int=5000,ssl: Optional[SSLContext]=None,debug: Optional[bool]=None,
            access_log_format: str="%(h)s %(r)s %(s)s %(b)s %(D)s",keep_alive_timeout: int=5,use_reloader: bool=False,
            loop: Optional[asyncio.AbstractEventLoop]=None,**kwargs: Any,
    ) -> None:
        """
        Arguments:
            host: 监听地址
            ssl: 可选的SSL上下文
            access_log_format: 日志格式化
            keep_alive_timeout: 超时秒数,在关闭之前保持的不活动连接数
            use_reloader: 自动重新加载代码更改
            loop: 创建服务器asyncio循环,如果没有则采用默认的
            
        """
        config = HyperConfig() # 是hypercorn(一个基于ASGIweb服务器)的配置
        config.access_log_format = access_log_format
        config.access_logger = create_serving_logger()
        if debug is not None:
            config.debug = debug
        config.error_logger = config.access_logger
        config.host = host
        config.keep_alive_timeout = keep_alive_timeout
        config.port = port
        config.ssl = ssl
        config.use_reloader = use_reloader

        scheme = 'http' if config.ssl is None else 'https'
        print("Running on {}://{}:{} (CTRL + C to quit)".format(scheme, config.host, config.port))  # noqa: T001, E501

        if loop is None: # 如果没有指定时间循环,创建一个事件循环
            loop = asyncio.get_event_loop()

        try:
            run_single(self, config, loop=loop) # 
        finally:
            # 重置第一个请求,以便重新使用
            self._got_first_request = False
            

 

def run_single(
        app: Type[ASGIFramework],config: Config,*,loop: asyncio.AbstractEventLoop,sock: Optional[socket]=None,is_child: bool=False,
) -> None:
    """创建一个服务器,在给定的选项配置的情况下运行应用程序。

    Arguments:
        app: The ASGI Framework to run.
        config: The configuration that defines the server.
        loop: Asyncio loop to create the server in, if None, take default one.
    """
    if loop is None:
        warnings.warn('Event loop is not specified, this can cause unexpected errors')
        loop = asyncio.get_event_loop()

    if config.pid_path is not None and not is_child:
        _write_pid_file(config.pid_path)

    loop.set_debug(config.debug)

    if hasattr(app, 'startup'):
        loop.run_until_complete(app.startup())  # type: ignore

    if sock is not None:
        create_server = loop.create_server(
            lambda: Server(app, loop, config), ssl=config.ssl, sock=sock, reuse_port=is_child,
        )
    elif config.file_descriptor is not None:
        sock = socket_fromfd(config.file_descriptor, AF_UNIX, SOCK_STREAM)
        create_server = loop.create_server(
            lambda: Server(app, loop, config), ssl=config.ssl, sock=sock,
        )
    elif config.unix_domain is not None:
        create_server = loop.create_unix_server(
            lambda: Server(app, loop, config), config.unix_domain, ssl=config.ssl,
        )
    else:
        create_server = loop.create_server(
            lambda: Server(app, loop, config), host=config.host, port=config.port, ssl=config.ssl,
            reuse_port=is_child,
        )
    server = loop.run_until_complete(create_server)

    if platform.system() == 'Windows':
        loop.create_task(_windows_signal_support())

    try:
        loop.add_signal_handler(signal.SIGINT, _raise_shutdown)
        loop.add_signal_handler(signal.SIGTERM, _raise_shutdown)
    except NotImplementedError:
        pass  # Unix only

    reload_ = False
    try:
        if config.use_reloader:
            loop.run_until_complete(_observe_changes())
            reload_ = True
        else:
            loop.run_forever()
    except (SystemExit, KeyboardInterrupt):
        pass
    finally:
        server.close()
        loop.run_until_complete(server.wait_closed())
        loop.run_until_complete(loop.shutdown_asyncgens())

        try:
            loop.remove_signal_handler(signal.SIGINT)
            loop.remove_signal_handler(signal.SIGTERM)
        except NotImplementedError:
            pass  # Unix only

        if hasattr(app, 'cleanup'):
            loop.run_until_complete(app.cleanup())  # type: ignore
        loop.close()
    if reload_:
        # Restart this process (only safe for dev/debug)
        os.execv(sys.executable, [sys.executable] + sys.argv)

 

posted @ 2018-10-29 18:12  短毛兔  阅读(460)  评论(0编辑  收藏  举报