pub struct InMemoryReplayGuard { /* private fields */ }Expand description
A bounded, in-process ReplayGuard: an LRU map from id to the digest
accepted under it, its retention deadline, and the response it produced.
§Suitable when
One process is the sole consumer for the recipient VID it serves, and
losing the record on restart is acceptable — that is, the window in which a
replay could arrive is shorter than the process’s uptime, or the transport
will not redeliver across a restart.
§Not suitable when
The consumer is replicated. Two replicas behind a load balancer each hold
their own map, so the same document accepted by replica A is Fresh at
replica B and the consequential effect happens twice — the exact failure
item 11 exists to prevent. Replicated deployments MUST back
ReplayGuard with a store shared by every replica, which is why the seam
is a trait.
Eviction is by capacity as well as by retain_until: a burst of distinct
documents can push an older record out before its retention deadline, and a
replay arriving after that would be accepted. Size the capacity above the
number of distinct documents the widest acceptance window can hold.
Implementations§
Source§impl InMemoryReplayGuard
impl InMemoryReplayGuard
Sourcepub fn new(capacity: usize) -> InMemoryReplayGuard
pub fn new(capacity: usize) -> InMemoryReplayGuard
A guard retaining at most capacity records.
§Panics
If capacity is zero. A guard that retains nothing answers Fresh to
every arrival, which is indistinguishable from having no guard at all —
and would be a silent, total defeat of item 11 rather than a visible
misconfiguration.
Sourcepub fn len(&self) -> usize
pub fn len(&self) -> usize
Number of records currently retained. Exposed for tests and metrics.
Sourcepub fn purge_expired(&self, now: DateTime<Utc>)
pub fn purge_expired(&self, now: DateTime<Utc>)
Drop every record whose retain_until has passed.
claim already treats an individual expired
record as absent, so calling this is an optimisation (it reclaims
memory) rather than a correctness requirement.
Trait Implementations§
Source§impl Default for InMemoryReplayGuard
impl Default for InMemoryReplayGuard
Source§fn default() -> InMemoryReplayGuard
fn default() -> InMemoryReplayGuard
10 000 records — a few megabytes at typical document sizes, and enough to cover a five-minute acceptance window at ~33 documents per second.