Retry with full jitter
Write retry_call(call, rng, sleep, max_attempts=5, base_ms=200, cap_ms=10_000). It calls call(attempt) (attempt starts at 0) and returns its result. When call raises Retryable, wait and try again. The wait is a random whole number of milliseconds from 0 up to min(cap_ms, base_ms * 2**attempt): take int(rng.next() * ceiling). Call sleep(wait).
If the error has a retry_after_ms larger than the random wait, wait that long instead. After the last attempt, re-raise the Retryable error without waiting. Any other exception must propagate at once.
What Check tests
- A call that fails twice then works returns its result after two waits
- Each wait is at most its ceiling (200, then 400)
- After the last attempt the error is re-raised, with no wait after it
- Other errors are not retried
- A Retry-After longer than the random wait wins
Stuck? One hint at a time
The solution unlocks after your first Check. Try first: that is where the learning happens.
Output
Press Run to see what your program prints.