← retour aux snippets

retry: décorateur avec backoff exponentiel

Relancer une fonction sujette aux erreurs transitoires avec attente croissante.

python reliability #retry#backoff#decorator

objectif

Relancer une fonction sujette aux erreurs transitoires avec attente croissante.

code minimal

import time, functools

def retry(times=3, base=0.01, factor=2.0, exceptions=(Exception,)):
    def deco(fn):
        @functools.wraps(fn)
        def wrapper(*a, **kw):
            delay = base
            for i in range(times):
                try:
                    return fn(*a, **kw)
                except exceptions:
                    if i == times - 1:
                        raise
                    time.sleep(delay)
                    delay *= factor
        return wrapper
    return deco

attempts = {"n": 0}

@retry(times=3, base=0.001)
def flaky():
    attempts["n"] += 1
    if attempts["n"] < 2:
        raise RuntimeError("transient")
    return "ok"

print(flaky() == "ok")  # attendu: True

utilisation

# Ajustez times/base/factor selon la latence acceptable
print(True)

variante(s) utile(s)

import time
t0 = time.time()
time.sleep(0.002)
print(time.time() - t0 >= 0.002)

notes

  • Ne retryez pas les erreurs permanentes (validation, 4xx).
  • Ajoutez du jitter pour lisser les rafales côté serveur.