CP-RETRY-AND-RECOVER - Share calculations without merging requests or repeating their effects
- Situation: Requests repeat expensive calculations, replies can be lost, and a restart can erase some remembered results.
- Question: Which work may be shared while each logical request still has its required effect and reply?
- First useful result or blocker: Distinct reuse and request identities, a retention rule and a composed procedure, or the missing atomic operation or delivery condition.
- Start with: CMP.14 for required observations; CMP.3 for reusable calculations; CMP.10 for retained records. Return their results to CMP.14’s interaction argument.
- Stop or return: Keep a sufficient existing procedure. Changed effects, record retention or failure conditions reopen the affected claim. At-most-once effects alone promise neither a reply nor a deadline.
Suppose a request runs a deterministic calculation f(x) and adds its result to a shared counter and returns the counter value immediately after that addition. For the input in this example, f(x) = 5, and the counter starts at 0. CMP.14 - Compose Interacting Computations through Their Required Observations first distinguishes the intended observations: two independently intended requests must add twice; a retransmission of one request must not add again. A lost reply does not show whether the first addition occurred.
CMP.3 supplies a different distinction. A pure calculation of f(x) may be shared when its inputs and governing version make its returned result interchangeable. That reuse does not identify two independently intended additions. Give a logical request its own identifier k, reused only by its attempts, and keep its payload consistent. Two requests with the same x may reuse the calculated 5 while still adding 10 in total. If the calculation is cheap, there is no need to cache it.
These two identities determine what CMP.10 must represent: a cache for calculation results, when worthwhile, and a separate map from completed request identifiers to their payloads and returned results. Discarding a pure calculation’s cache entry only causes recomputation under the same conditions. Discarding a request’s completion record while an old attempt can still arrive can repeat an effect. The records’ retention rules cannot be borrowed from one another merely because both look like tables.
CMP.14 uses those records in the actual interaction. After obtaining the amount, the receiver must atomically either find k completed and recover its original reply, or add the amount and record that reply as k’s completed result. Sending the reply may follow. For one request the counter becomes 5; loss of its reply followed by a retry returns the stored 5 without another addition. A genuinely new request adds another 5 and receives 10. A later retry of the first request still receives its original 5. An efficient lookup table by itself supplies no atomicity for this composite operation.
Now let a restart preserve the counter but lose completed-request records. Retrying the first request can raise 5 to 10: calculation reuse may remain correct while the composed effect is wrong. Return to CMP.14’s failure model and CMP.10’s retention choice. Effect and completion result must survive together if that guarantee is required. Persisting an identifier in one place and performing an external service’s effect elsewhere does not close the crash interval between them; the missing operation or external guarantee remains a blocker.
Finally, keep the response question separate. Avoiding repeated effects does not require eventual message delivery. Eventual response does: it needs adequate retry, delivery, processing and retained-state conditions for both request and reply. Those conditions still provide no fixed deadline. Reopen only the affected assumption when it changes. The same separation applies to shared calculations, updates and message protocols beyond this counter example; the direct methods determine their actual identity, atomicity, storage and progress requirements.