我通过使用tenacity库成功实现了重试功能。感谢大家的指导。
from tenacity import retry, retry_if_result, stop_after_attempt
# 设置重试次数和可重试状态码
retries = 3
status_retries = (500, 502)
# 定义判断HTTP响应状态码是否需要重试的函数
def is_retryable_status_code(response):
global status_retries
return response.status_code in status_retries
# 使用装饰器实现带有状态码判断的重试功能
def retry_with_status(f) -> Any:
# 同步函数的重试包装器
@retry(stop=stop_after_attempt(retries), retry=retry_if_result(is_retryable_status_code))
def retry_wrapper(*args, **kwargs):
return f(*args, **kwargs)
# 异步函数的重试包装器
@retry(stop=stop_after_attempt(retries), retry=retry_if_result(is_retryable_status_code))
async def async_retry_wrapper(*args, **kwargs):
return await f(*args, **kwargs)
# 根据调用函数是否为异步决定使用哪种重试包装器
def wrapper(*args, **kwargs) -> Any:
global retries, status_retries
# 如果被装饰的函数所在对象中包含自定义的重试次数和状态码,进行更新
if 'retry' in dir(args[0]) and 'status_retries' in dir(args[0]):
retries = args[0].retries
status_retries = args[0].status_retries
# 判断被装饰函数是否为异步函数,并相应地返回同步或异步重试包装器的结果
if asyncio.iscoroutinefunction(f):
return async_retry_wrapper(*args, **kwargs)
else:
return retry_wrapper(*args, **kwargs)
# 返回最终的装饰器函数
return wrapper