What the interviewer looks for: functools.wraps, retrying only on specific exceptions (not all of them), re-raising on the last attempt, and jitter so that not all clients hit at the same time.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | # ====================================================================== # Q: Write a decorator that retries with exponential backoff. # # What the interviewer looks for: functools.wraps, retrying only on specific # exceptions (not all of them), re-raising on the last attempt, and jitter so # that not all clients hit at the same time. # ====================================================================== import functools, random, time def retry(exceptions, tries=3, base_delay=0.5): def decorator(func): @functools.wraps(func) # keeps __name__, __doc__ def wrapper(*args, **kwargs): for attempt in range(1, tries + 1): try: return func(*args, **kwargs) except exceptions: if attempt == tries: raise time.sleep(base_delay * 2 ** (attempt - 1) + random.uniform(0, 0.1)) return wrapper return decorator @retry((ConnectionError, TimeoutError), tries=5) def fetch_erp_prices(): ... |