Exactly-once RPC: retries are only half the story
Posted
An RPC client cannot distinguish a lost request from a lost response. Retrying helps progress, but it can also execute the same logical operation twice.
Retrying a naive server
The walkthrough drops the first response, fires the retry timer, and delivers the duplicate request. Watch the at-most-once invariant—not merely the client’s result.
Naive RPC simulator
Use Next to begin the guided execution.
No request in flight
- Inbox
- 0
- Timers
- 0
0 executions across 0 requests; cached request IDs: none
- Inbox
- 0
- Timers
- 0
Pending work
0 queuedNo messages or timers are pending.
Network faults
No active faults
Inspector
Select a node or pending object to inspect it.
Correctness
Invariants
No violations at this step
Goals
- Client received resultNot currently trueNot reached yet
Execution timeline
What can happen next
Deduplicating by request ID
The second server caches the first result and returns that result when the same request ID arrives again.
Deduplicating RPC simulator
Use Next to begin the guided execution.
No request in flight
- Inbox
- 0
- Timers
- 0
0 executions across 0 requests; cached request IDs: none
- Inbox
- 0
- Timers
- 0
Pending work
0 queuedNo messages or timers are pending.
Network faults
No active faults
Inspector
Select a node or pending object to inspect it.
Correctness
Invariants
No violations at this step
Goals
- Client received resultNot currently trueNot reached yet
Execution timeline
What can happen next
Safety is not liveness
Try dropping every response or partitioning the link. The server can preserve at-most-once execution while the client never reaches its response-received goal. Completion still depends on some retry and response eventually being delivered.