in neuron_explainer/api_client.py [0:0]
def async_exponential_backoff(retry_on=lambda err: True):
"""
Returns a decorator which retries the wrapped function as long as the specified retry_on
function returns True for the exception, applying exponential backoff with jitter after
failures, up to a retry limit.
"""
init_delay_s = 1
max_delay_s = 10
backoff_multiplier = 2.0
jitter = 0.2
def decorate(f):
@wraps(f)
async def f_retry(self, *args, **kwargs):
max_tries = 200
delay_s = init_delay_s
for i in range(max_tries):
try:
return await f(self, *args, **kwargs)
except Exception as err:
if i == max_tries - 1:
print(f"Exceeded max tries ({max_tries}) on HTTP request")
raise
if not retry_on(err):
print("Unretryable error on HTTP request")
raise
jittered_delay = random.uniform(delay_s * (1 - jitter), delay_s * (1 + jitter))
await asyncio.sleep(jittered_delay)
delay_s = min(delay_s * backoff_multiplier, max_delay_s)
return f_retry
return decorate