超时后获得完成的 aiohttp 并行请求
get completed aiohttp parallel requests after timeout
我正在使用 aiohttp 执行一些并行 HTTP post 请求。
我必须全局设置超时(在 ClientSession 上),以免超过阈值。
问题是我想获取我在阈值之前完成的(会话中的部分)响应,例如,如果会话包含 10 个请求并且在超时之前我已经完成了其中的 5 个,我想取这5个的结果。但是我还没想好怎么办。
我使用的代码是这样的:
import aiohttp
import asyncio
import requests
async def fetch(session):
async with session.get("https://amazon.com") as response:
return response.status
async def main(n, timeout):
async with aiohttp.ClientSession(timeout=timeout) as session:
return await asyncio.gather(*(fetch(session) for _ in range(n)))
timeout = aiohttp.ClientTimeout(total=0.4)
res = asyncio.run(main(10, timeout))
print(res)
使用 timeout = 0.4
会引发 asyncio.TimeoutError
,我不知道如何获得部分执行的响应。
比如我把超时时间设置为5秒,所有的请求都完成了,我得到了十个列表200
。
谢谢
使用asyncio.wait代替asyncio.gather
另请参阅 以了解有关差异的更多信息。
注意:wait 的 timeout
参数以秒表示。
最重要的是,您可能根本不需要为 ClientSession 指定超时。
修改后的代码(为了增加响应时间的差异,我添加了一些不同的来源并执行了 20 个请求)
import asyncio
import random
import aiohttp
import requests
sources = ["amazon.com", "hotmail.com", "whosebug.com"]
async def fetch(session):
rnd = random.choice(sources)
async with session.get(f"https://{rnd}") as response:
return response.status
async def main(n, timeout):
async with aiohttp.ClientSession() as session:
completed, pending = await asyncio.wait(
[fetch(session) for _ in range(n)],
timeout=timeout
)
for t in pending: # cancel the pending tasks
t.cancel()
return [t.result() for t in completed]
timeout = 0.5
res = asyncio.run(main(20, timeout))
print(res)
随着 timeout
值的增加,0.3、0.5 和 0.8 产生
(.venv) async_req_timeout $ python async_req_timeout.py
[200, 200]
(.venv) async_req_timeout $ python async_req_timeout.py
[200, 200, 200, 200, 200, 200, 200, 200, 200, 200]
(.venv) (base) async_req_timeout $ python async_req_timeout.py
[200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200]
我正在使用 aiohttp 执行一些并行 HTTP post 请求。
我必须全局设置超时(在 ClientSession 上),以免超过阈值。
问题是我想获取我在阈值之前完成的(会话中的部分)响应,例如,如果会话包含 10 个请求并且在超时之前我已经完成了其中的 5 个,我想取这5个的结果。但是我还没想好怎么办。
我使用的代码是这样的:
import aiohttp
import asyncio
import requests
async def fetch(session):
async with session.get("https://amazon.com") as response:
return response.status
async def main(n, timeout):
async with aiohttp.ClientSession(timeout=timeout) as session:
return await asyncio.gather(*(fetch(session) for _ in range(n)))
timeout = aiohttp.ClientTimeout(total=0.4)
res = asyncio.run(main(10, timeout))
print(res)
使用 timeout = 0.4
会引发 asyncio.TimeoutError
,我不知道如何获得部分执行的响应。
比如我把超时时间设置为5秒,所有的请求都完成了,我得到了十个列表200
。
谢谢
使用asyncio.wait代替asyncio.gather
另请参阅
注意:wait 的 timeout
参数以秒表示。
最重要的是,您可能根本不需要为 ClientSession 指定超时。
修改后的代码(为了增加响应时间的差异,我添加了一些不同的来源并执行了 20 个请求)
import asyncio
import random
import aiohttp
import requests
sources = ["amazon.com", "hotmail.com", "whosebug.com"]
async def fetch(session):
rnd = random.choice(sources)
async with session.get(f"https://{rnd}") as response:
return response.status
async def main(n, timeout):
async with aiohttp.ClientSession() as session:
completed, pending = await asyncio.wait(
[fetch(session) for _ in range(n)],
timeout=timeout
)
for t in pending: # cancel the pending tasks
t.cancel()
return [t.result() for t in completed]
timeout = 0.5
res = asyncio.run(main(20, timeout))
print(res)
随着 timeout
值的增加,0.3、0.5 和 0.8 产生
(.venv) async_req_timeout $ python async_req_timeout.py
[200, 200]
(.venv) async_req_timeout $ python async_req_timeout.py
[200, 200, 200, 200, 200, 200, 200, 200, 200, 200]
(.venv) (base) async_req_timeout $ python async_req_timeout.py
[200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200]