Skip to content
C.W.K.
Stream
Lesson 03 of 05 · published

Retry Without Duplication

~12 min · idempotency, retry, deduplication, failure

Level 0Dry Nib
0 XP0/36 lessons0/12 achievements
0/100 XP to next level100 XP to go0% complete
"Repeat delivery; preserve one intended effect."

Define one intended effect

Networks repeat themselves. A tap can be delivered twice, a timeout can hide a success, and a worker can restart after writing output but before acknowledging it. Retry is normal; duplicate effect is the bug.

Retry the same durable row

Current Inkwell retries a failed durable job by moving that same row back to queued. The guarded update is a no-op for queued, running, or done work, so a repeated retry command cannot spawn another job.

Do not confuse retry with another request

Treating every retry as a new job can produce competing translations. Voice is on-demand and is not represented by a durable job. Source edits supersede pending review work rather than hiding a second identity inside the retry command.

Operational invariant. Repeat delivery; preserve one intended effect.

Put crashes on the timeline

Test “Retry Without Duplication” on a timeline where the process may disappear before acceptance, after commit, after claim, after the external call, or after output storage. At every cut, state what the database knows. A repeated request must not duplicate cost or prose.

Design it

Design retry handling for the case where the client timed out after the server committed. Name statuses, timestamps, and attempt rows. Explain which evidence authorizes recovery instead of letting a cleanup script guess.

Observability is recoverability

An operator should distinguish queued, running, failed, and done with one query and know the next safe action. A silent unknown called a queue has already lost the work.

Code

Enforce logical uniqueness·sql
UPDATE jobs
SET status = 'queued',
    error = NULL,
    started_at = NULL,
    finished_at = NULL
WHERE id = :job_id AND status = 'failed';

SELECT id, status, error
FROM jobs
WHERE id = :job_id;
-- Repeating this command reuses the same durable job row.

External links

Exercise

Design retry handling for the case where the client timed out after the server committed.
Hint
Move the crash point one step at a time.

Progress

Progress is local-only — sign in to sync across devices.
Spotted a bug or have feedback on this page?Report an Issue

Comments 0

🔔 Reply notifications (sign in)
Sign inPlease sign in to comment.

No comments yet — be the first.