如何从 Quart 获取事件循环

2023-12-30

你好,我对 Python 相当陌生,我正在尝试将 Flask 上的现有应用程序转换为 Quart (https://gitlab.com/pgjones/quart https://gitlab.com/pgjones/quart)它应该构建在 asyncio 之上,因此我可以使用 Goblin OGM 与 JanusGraph 或 TinkerPop 进行交互。根据我在 Goblin 上找到的示例,我需要获取一个事件循环来异步运行命令。

    >>> import asyncio
    >>> from goblin import Goblin

    >>> loop = asyncio.get_event_loop()
    >>> app = loop.run_until_complete(
    ...     Goblin.open(loop))
    >>> app.register(Person, Knows)

然而,我找不到从 Quart 获取事件循环的方法,即使它是构建在 asyncio 之上的。

有谁知道我怎样才能得到它?任何帮助将不胜感激。


TL;DR 要获取事件循环,请调用asyncio.get_event_loop().

在基于 asyncio 的应用程序中,事件循环通常不属于 Quart 或任何其他协议/应用程序级组件,它由 asyncio 或可能是像 uvloop 这样的加速器提供。事件循环是通过调用获得的asyncio.get_event_loop(),有时设置为asyncio.set_event_loop().

这就是夸脱的app.run()用于运行应用程序,这意味着它使用 asyncio 为主线程创建的默认事件循环。在你的情况下,你可以简单地调用夸脱run()注册后Goblin:

loop = asyncio.get_event_loop()
goblin_app = loop.run_until_complete(Goblin.open(loop))
goblin_app.register(Person, Knows)
quart_app = Quart(...)
# ... @app.route, etc

# now they both run in the same event loop
quart_app.run()

The above should answer the question in the practical sense. But that approach wouldn't work if more than one component insisted on having their own run() method that spins the event loop - since app.run() doesn't return, you can only invoke one such function in a thread.

但如果你仔细观察,就会发现事实并非如此quart任何一个。虽然夸脱示例确实使用app.run()为应用程序提供服务,如果你看一下实现app.run(),你会看到它调用了便利函数run_app(),它简单地创建了一个服务器并永远旋转主循环:

def run_app(...):
    loop = asyncio.get_event_loop()
    # ...
    create_server = loop.create_server(
        lambda: Server(app, loop, ...), host, port, ...)
    server = loop.run_until_complete(create_server)
    # ...
    loop.run_forever()

如果您需要控制事件循环的实际运行方式,您始终可以自己完成:

# obtain the event loop from asyncio
loop = asyncio.get_event_loop()

# hook Goblin to the loop
goblin_app = loop.run_until_complete(Goblin.open(loop))
goblin_app.register(Person, Knows)

# hook Quart to the loop
quart_server = loop.run_until_complete(loop.create_server(
        lambda: quart.serving.Server(quart_app, loop), host, port))

# actually run the loop (and the program)
try:
    loop.run_forever()
except KeyboardInterrupt:  # pragma: no cover
    pass
finally:
    quart_server.close()
    loop.run_until_complete(quart_server.wait_closed())
    loop.run_until_complete(loop.shutdown_asyncgens())
    loop.close()
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何从 Quart 获取事件循环 的相关文章

随机推荐