我有一个应用程序,它将协同程序添加到已经运行的事件循环中.这些协同程序的参数依赖于I/O,并且在我最初启动事件循环时不可用 - 使用loop.run_forever(),所以我稍后添加任务.为了演示这种现象,这里有一些示例代码:
import asyncio
from threading import Thread
from time import sleep
loop = asyncio.new_event_loop()
def foo():
loop.run_forever()
async def bar(s):
while True:
await asyncio.sleep(1)
print("s")
#loop.create_task(bar("A task created before thread created & before loop started"))
t = Thread(target=foo)
t.start()
sleep(1)
loop.create_task(bar("secondary task"))
Run Code Online (Sandbox Code Playgroud)
奇怪的行为是,当调用loop.run_forever()时,循环中至少有一个任务时,一切都按预期工作.即当注释行没有被注释掉时.
但是当它被注释掉时,如上所示,没有打印任何内容,看起来我无法向event_loop添加任务.我应该避免在不添加单个任务的情况下调用run_forever()吗?我不明白为什么这应该是一个问题.在运行后将任务添加到event_loop是标准的,为什么空案例会成为问题?
我对图书馆越来越熟悉,但我被以下情况难住了:
我希望不断处理来自两个不同网站的 websocket 的更新消息。
但是我无法使用单个会话变量实现这一点,因为 aiohttp.ClientSession() 对象应该存在于协程中。
import asyncio
import aiohttp
url1 = 'wss://example.com'
async def main():
session = aiohttp.ClientSession()
async with session.ws_connect(url1) as ws1:
async for msg in ws1:
# do some processing
loop = asyncio.get_event_loop()
loop.create_task(main())
loop.run_forever()
Run Code Online (Sandbox Code Playgroud)
以上将适用于单个 websocket 连接。但是因为ws:中的async for msg是一个无限循环,所以我看不到我可以把这个异步循环的 ws2 版本放在哪里。
如果您检查Quart库,app.run()
只需建立一些配置,然后使用asyncio.run(serve(self, config))
,其中 serve 来自from hypercorn.asyncio import serve
。
因此,即使您通过运行Quart应用程序python myapp.py
,它不是已经在使用Hypercorn服务器了吗?
特别是,this 和 running via 有hypercorn myapp:app
什么区别?
https://pgjones.gitlab.io/quart/deployment.html
不建议在生产中直接运行 Quart(通过 run())。相反,建议使用 Hypercorn 或替代 ASGI 服务器运行 Quart。Hypercorn 与 Quart 一起安装,默认情况下用于处理请求(例如使用 run())。
所以听起来,即使Hypercorn默认使用 来处理请求run()
,也不建议使用run()
? 还有人糊涂吗?
我将订阅同一服务器的多个 websocket 频道。编写一个管理器来根据 Json 中存在的标签将我收到的各种类型的更新分配给不同的队列是可能的,但是在我的应用程序中创建多个 websocket 客户端对象会节省编程时间,因此每个 websocket 对象仅订阅单个通道。这是一个明智的想法还是我应该坚持使用单个 websocket 客户端?
当我们写:
fn foo<'a, 'b>(x: &'a u32, y: &'b u32) -> &'a u32 {
x
}
Run Code Online (Sandbox Code Playgroud)
为什么我们不将'a
s 和'b
s 称为生命周期参数而不是通用生命周期参数?这只是一种语法方式,可以根据参数的生命周期向编译器传达对返回引用生命周期的约束。我正在努力了解在此处包含“通用”一词的理由。