At the end of lesson 2.8.2, every tender was in the list twice: the import ran twice and wrote twice. The same problem has a second side, and it's more dangerous. A network is never completely reliable, so a good client asks again after an error. But if it asks again where its first request has already taken effect, something happens twice: a mail, a booking, a payment.
In this lesson you learn both sides: retrying where it's harmless, and building idempotently so that a retry does no harm. At the end, the Kladde asks TED again after a disruption, and its import writes every notice exactly once, no matter how often it runs.
Temporary or final
Not every error is worth a second attempt. For each, ask: Can the same request succeed right afterwards?
| Kind | Examples | Again? |
|---|---|---|
| temporary | timeout, dropped connection, 408 Request Timeout, 429 Too Many Requests, 500, 502, 503, 504 |
yes, with a pause |
| final | 400 Bad Request, 401, 403, 404, 422, a redirect for a machine client |
no, the same request fails again |
Whoever retries waits in between, and always longer: two seconds, then four, then eight. That's called exponential backoff. A service
that's overloaded at the moment gets room to breathe. In addition there's jitter, a random share of every wait. Without it, a hundred
clients that saw an error at the same moment would also ask again at the same moment and knock the service over again right away. If the
service sends a Retry-After header with its 429 or 503, its wait applies.