feat: automatic retry with backoff#108
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Review Summary by QodoAdd automatic retry with exponential back-off for transient errors
WalkthroughsDescription• Adds automatic retry with exponential back-off for transient failures • Retries HTTP 5xx errors and network failures by default, skips 4xx errors • Uses full-jitter algorithm to prevent thundering-herd problem • Opt-in feature with sensible defaults (3 retries, 500ms base, 30s cap) • Includes comprehensive test coverage and documentation Diagramflowchart LR
A["Request fails"] --> B["RetryManager evaluates error"]
B --> C{"shouldRetry predicate?"}
C -->|5xx or network error| D["Compute exponential delay"]
C -->|4xx client error| E["Throw immediately"]
D --> F["Wait with jitter"]
F --> G["Retry attempt"]
G --> H{"Success?"}
H -->|Yes| I["Return result"]
H -->|No| B
B -->|Max retries exhausted| E
File Changes1. packages/tmdb/src/utils/retry.ts
|
Code Review by Qodo
1.
|
Summary
Complements the existing rate limiter with automatic retry logic for transient failures. When enabled, the client retries failed requests up to a configurable number of times using full-jitter exponential back-off before propagating the error.
Opt-in — disabled by default, no behaviour change for existing consumers.
What's new
retryoption onTMDB/ApiClientDefault retry behaviour
TMDBErrorwithhttp_status_code >= 500)TMDBError)Back-off algorithm
Full-jitter exponential:
delay = random(0, min(base * 2^(attempt-1), max_delay)). Full jitter distributes retry load evenly and avoids the thundering-herd problem when multiple clients retry after the same outage.Implementation details
RetryManager(utils/retry.ts) — self-contained class that ownsexecute<T>(fn, sleep?),delayFor(attempt), andshouldRetry. The injectablesleepargument makes it trivially testable without real timers.ApiClient.execute()— the existing per-attempt closure already holds the rate-limiteracquire()call, so each retry attempt correctly acquires its own rate-limit slot with no extra logic.RetryOptionsis exported from the package public surface (utils/index.ts).Files changed
RetryManager+RetryOptionsretryfield added toTMDBOptionsRetryManagerintoexecute()RetryOptionsretryoption entry + sectionTesting
36 new tests across two suites:
RetryManagerunit tests — success path, 5xx retry, network error retry, 4xx no-retry, exhaustion,shouldRetrypredicate (sync + async), jitter bounds,max_delay_msclamping, constructor validationApiClientintegration tests —retry: trueshorthand, 5xx recovery, network error recovery, 4xx no-retry, exhaustion, custom predicate,mutate()coverage, rate-limit slot per attempt