pub struct CompletedResults<T> { /* private fields */ }Expand description
The transition table, with no lock and no I/O.
§What &mut self guarantees and what it does not
It guarantees the transitions are consistent within one caller. It does not
make claim atomic against another thread, because a
&mut self method only excludes callers that share the borrow. An adapter
holds this behind a Mutex — one acquisition per operation, and the lock
is released across the execution rather than held across it, so a slow tool
does not block every other key. That is the same division as the registry’s
compare-and-swap publish: the state machine is domain, the atomicity is the
adapter’s, and neither is asked to do the other’s job.
Implementations§
Source§impl<T> CompletedResults<T>
impl<T> CompletedResults<T>
Sourcepub fn with_capacity(capacity: NonZeroUsize) -> Self
pub fn with_capacity(capacity: NonZeroUsize) -> Self
A store holding at most capacity keys.
Bounded because a client chooses the keys: an unbounded map keyed by a peer-supplied id is a memory exhaustion primitive, and the wire offers nothing that would stop a client from minting a fresh id per request.
A capacity of zero is refused at the type level — such a store could never complete anything, so every call would fail for a reason that has nothing to do with the work itself.
Sourcepub fn claim(
&mut self,
key: &IdempotencyKey,
) -> Result<Claim<T>, IdempotencyError>where
T: Clone,
pub fn claim(
&mut self,
key: &IdempotencyKey,
) -> Result<Claim<T>, IdempotencyError>where
T: Clone,
Takes ownership of key, or reports why it could not.
§Errors
IdempotencyError::StoreFull when the store is at capacity, key is
not already present, and every slot is held by a request still running.
That is genuine overload, and refusing the new request is visible where
discarding a live claim would let two callers run one request.
§Retention
When the store is full and key is new, the oldest completed
result is dropped to make room. A retry replays its recorded result for
as long as it is among the last capacity completed requests; a retry
of something older than that runs again. The alternative, refusing every
new key once the store has filled with finished work, turns a long-lived
session into one that fails every call after the first capacity, which
is the common case and not an edge. A dropped connection is retried in
seconds, so the window is far longer than any retry needs.
T: Clone because handing a recorded result to the retrying caller
leaves the recorded copy in place — a claim that consumed it would break
the second retry, which is the case the store exists for.
Sourcepub fn complete(
&mut self,
token: &ClaimToken,
result: T,
) -> Result<(), StaleClaim>
pub fn complete( &mut self, token: &ClaimToken, result: T, ) -> Result<(), StaleClaim>
Records the result of a claim.
§Errors
StaleClaim when the token is not the current holder of the key —
because the claim was abandoned and re-taken, or because it was never
valid. A stale completion is refused rather than applied: the attempt
that replaced it is the one whose result the retrying client is entitled
to, and writing over it would give two callers two different answers for
one request id.
Sourcepub fn abandon(&mut self, token: &ClaimToken) -> Result<(), StaleClaim>
pub fn abandon(&mut self, token: &ClaimToken) -> Result<(), StaleClaim>
Releases a claim so a later retry can execute.
§Errors
StaleClaim when the token is not the current holder. Releasing a
claim another attempt now owns would hand the same key to a third
caller while the second is still running it.
Sourcepub fn completed(&self, key: &IdempotencyKey) -> Option<&T>
pub fn completed(&self, key: &IdempotencyKey) -> Option<&T>
Whether a key has completed, without claiming it.
Sourcepub fn is_in_flight(&self, key: &IdempotencyKey) -> bool
pub fn is_in_flight(&self, key: &IdempotencyKey) -> bool
Whether a key is held by a live claim.