nei*_*iii 3 python python-requests python-asyncio aiohttp
我本质上是在制作一个 pinger,它有一个密钥/webhook 对的二维列表,并在 ping 一个密钥后,将响应发送到 webhook
二维列表如下:
some_list = [["key1", "webhook1"], ["key2", "webhook2"]]
Run Code Online (Sandbox Code Playgroud)
我的程序本质上是一个循环,我不太确定如何some_list在函数中旋转数据。
这是我的脚本的一个小演示:
some_list = [["key1", "webhook1"], ["key2", "webhook2"]]
Run Code Online (Sandbox Code Playgroud)
我试过了:
async def do_ping(some_pair):
async with aiohttps.ClientSession() as s:
tasks = await gen_tasks(s, some_pair)
results = await asyncio.gather(*tasks*)
sleep(10)
await do_ping(some_pair)
Run Code Online (Sandbox Code Playgroud)
但由于该do_ping函数是一个自调用循环,它只是一遍又一遍地调用第一个函数,而永远不会调用后面的函数。希望找到解决方案,无论是线程还是类似的,如果您有更好的构造some_list值的方法(我认为是字典),也请随意放弃该反馈
您使方法成为递归的await do_ping(some_pair),它永远不会结束以继续循环main。我会像这样重构应用程序:
async def do_ping(some_pair):
async with aiohttps.ClientSession() as s:
while True:
tasks = await gen_tasks(s, some_pair)
results = await asyncio.gather(*tasks)
await asyncio.sleep(10)
async def main():
tasks = [do_ping(entry) for entry in some_list]
await asyncio.gather(*tasks)
if __name__ == "__main__":
asyncio.run(main())
Run Code Online (Sandbox Code Playgroud)
或者,您可以将重复和睡眠逻辑移至main:
async def do_ping(some_pair):
async with aiohttps.ClientSession() as s:
tasks = await gen_tasks(s, some_pair)
results = await asyncio.gather(*tasks)
async def main():
while True:
tasks = [do_ping(entry) for entry in some_list]
await asyncio.gather(*tasks)
await asyncio.sleep(10)
if __name__ == "__main__":
asyncio.run(main())
Run Code Online (Sandbox Code Playgroud)
您还可以在调用睡眠之前启动任务,然后再收集它们。这将使 ping 更加一致地以 10 秒间隔开始,而不是 10 秒 + 收集结果所需的时间:
async def main():
while True:
tasks = [
asyncio.create_task(do_ping(entry))
for entry in some_list
]
await asyncio.sleep(10)
await asyncio.wait(tasks)
Run Code Online (Sandbox Code Playgroud)
编辑 正如creolo所指出的,您应该只创建一个ClientSession对象。请参阅https://docs.aiohttp.org/en/stable/client_reference.html
Session封装了一个连接池(连接器实例),默认支持keepalive。除非您在应用程序的生命周期内连接到大量未知数量的不同服务器,否则建议您在应用程序的生命周期内使用单个会话,以便从连接池中受益。
async def do_ping(session, some_pair):
tasks = await gen_tasks(session, some_pair)
results = await asyncio.gather(*tasks)
async def main():
async with aiohttp.ClientSession() as session:
while True:
tasks = [
asyncio.create_task(do_ping(session, entry))
for entry in some_list
]
await asyncio.sleep(10)
await asyncio.wait(tasks)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
8349 次 |
| 最近记录: |