退避只重试失败的 API 调用而不是所有 API 调用与异步
Backoff to retry only the failing the API call instead of all the API calls with asyncio
我正在使用具有速率限制的 API 提取信息。我正在以异步方式执行此操作,以使用 asyncio 和 aiohttp 加快进程。我以 10 个为一组收集电话,所以我每次都进行 10 个并发调用。如果我收到 429,我会等待 2 分钟,然后重试...对于重试部分,我正在使用退避装饰器。
我的问题是重试是针对 10 次调用执行的,而不仅仅是针对失败的调用...我不确定该怎么做:
@backoff.on_exception(backoff.expo,aiohttp.ClientError,max_tries=20,logger=my_logger)
async def get_symbols(size,position):
async with aiohttp.ClientSession() as session:
queries = get_tasks(session,size,position)
responses = await asyncio.gather(*queries)
print("gathering responses")
for response in responses:
if response.status == 429:
print(response.headers)
print("Code 429 received waiting for 2 minutes")
print(response)
time.sleep(120)
raise aiohttp.ClientError()
else:
query_data = await response.read()
有没有人有办法只执行失败的调用而不是整个调用?
您的代码中有两个问题。首先是重复的 sleep
——您可能不理解 backoff
是如何工作的。它的重点是 1) 尝试,2) 如果出现错误,睡眠会以指数方式增加延迟,3) 为您重试 function/coroutine。其次,是get_symbols
被backoff
装饰了,显然是整体重试了
如何改进?
- 装饰个性化请求功能
- 让
backoff
做它的“休眠”工作
- 让
aiohttp
通过在ClientSession
初始化程序 中设置raise_for_status=True
来为非200 HTTP重新提议代码引发它来完成它的工作
它应该如下所示。
@backoff.on_exception(backoff.expo, aiohttp.ClientError, max_tries=20)
async def send_task(client, params):
async with client.get('https://python.org/', params=params) as resp:
return await resp.text()
def get_tasks(client, size, position):
for params in get_param_list(size, position)
yield send_task(client, params)
async def get_symbols(size,position):
async with aiohttp.ClientSession(raise_for_status=True) as client:
tasks = get_tasks(session, size, position)
responses = await asyncio.gather(*tasks)
for response in responses:
print(await response.read())
我正在使用具有速率限制的 API 提取信息。我正在以异步方式执行此操作,以使用 asyncio 和 aiohttp 加快进程。我以 10 个为一组收集电话,所以我每次都进行 10 个并发调用。如果我收到 429,我会等待 2 分钟,然后重试...对于重试部分,我正在使用退避装饰器。
我的问题是重试是针对 10 次调用执行的,而不仅仅是针对失败的调用...我不确定该怎么做:
@backoff.on_exception(backoff.expo,aiohttp.ClientError,max_tries=20,logger=my_logger)
async def get_symbols(size,position):
async with aiohttp.ClientSession() as session:
queries = get_tasks(session,size,position)
responses = await asyncio.gather(*queries)
print("gathering responses")
for response in responses:
if response.status == 429:
print(response.headers)
print("Code 429 received waiting for 2 minutes")
print(response)
time.sleep(120)
raise aiohttp.ClientError()
else:
query_data = await response.read()
有没有人有办法只执行失败的调用而不是整个调用?
您的代码中有两个问题。首先是重复的 sleep
——您可能不理解 backoff
是如何工作的。它的重点是 1) 尝试,2) 如果出现错误,睡眠会以指数方式增加延迟,3) 为您重试 function/coroutine。其次,是get_symbols
被backoff
装饰了,显然是整体重试了
如何改进?
- 装饰个性化请求功能
- 让
backoff
做它的“休眠”工作 - 让
aiohttp
通过在ClientSession
初始化程序 中设置
raise_for_status=True
来为非200 HTTP重新提议代码引发它来完成它的工作
它应该如下所示。
@backoff.on_exception(backoff.expo, aiohttp.ClientError, max_tries=20)
async def send_task(client, params):
async with client.get('https://python.org/', params=params) as resp:
return await resp.text()
def get_tasks(client, size, position):
for params in get_param_list(size, position)
yield send_task(client, params)
async def get_symbols(size,position):
async with aiohttp.ClientSession(raise_for_status=True) as client:
tasks = get_tasks(session, size, position)
responses = await asyncio.gather(*tasks)
for response in responses:
print(await response.read())