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)
相關文章
相關標籤/搜索