Skip to main content

Deduplicator

Struct Deduplicator 

Source
pub struct Deduplicator { /* private fields */ }
Expand description

Deduplicates requests by key within a TTL window.

§Guarantees

  • Deterministic: same key always maps to the same result
  • Thread-safe via Arc<Mutex<_>>
  • Entries expire after ttl
  • Optional max_entries cap bounds memory independently of TTL

Implementations§

Source§

impl Deduplicator

Source

pub fn new(ttl: Duration) -> Self

Create a new deduplicator with the given TTL.

Source

pub fn with_max_entries(self, max: usize) -> Result<Self, AgentRuntimeError>

Set a hard cap on the number of cached (completed) entries.

When the cache is full the oldest entry (by insertion time) is evicted before the new entry is stored. This bounds memory growth for workloads where all request keys are unique and the TTL has not yet expired.

§Returns
  • Err(AgentRuntimeError::Orchestration) if max == 0
Source

pub fn check_and_register( &self, key: &str, ) -> Result<DeduplicationResult, AgentRuntimeError>

Check whether key is new, cached, or in-flight.

Marks the key as in-flight if it is new.

Source

pub fn check( &self, key: &str, ttl: Duration, ) -> Result<DeduplicationResult, AgentRuntimeError>

Check deduplication state for a key with a per-call TTL override.

Marks the key as in-flight if it is new. Ignores the stored TTL and uses ttl instead for expiry checks.

Source

pub fn dedup_many( &self, requests: &[(&str, Duration)], ) -> Result<Vec<DeduplicationResult>, AgentRuntimeError>

Check deduplication state for multiple keys at once.

Returns results in the same order as requests. Each entry is (key, ttl) — same signature as check.

Acquires the internal mutex once for the entire batch, avoiding the per-key lock overhead of calling check in a loop.

Source

pub fn complete( &self, key: &str, result: impl Into<String>, ) -> Result<(), AgentRuntimeError>

Complete a request: move from in-flight to cached with the given result.

If max_entries is configured and the cache is full, the oldest cached entry (by insertion time) is evicted before the new one is stored.

Source

pub fn fail(&self, key: &str) -> Result<(), AgentRuntimeError>

Remove a key from in-flight tracking without caching a result.

Call this when an in-flight operation fails so that subsequent callers are not permanently blocked by a stuck InProgress entry for the full TTL.

Source

pub fn in_flight_count(&self) -> Result<usize, AgentRuntimeError>

Return the number of keys currently in-flight (not yet completed or failed).

Source

pub fn in_flight_keys(&self) -> Result<Vec<String>, AgentRuntimeError>

Return a snapshot of all keys currently in-flight.

Source

pub fn cached_count(&self) -> Result<usize, AgentRuntimeError>

Return the number of keys currently in the completed result cache.

Note: expired entries are only removed lazily on the next check* call.

Source

pub fn cached_keys(&self) -> Result<Vec<String>, AgentRuntimeError>

Return a snapshot of all keys that have cached results.

Expired entries are included (they are removed lazily). Use purge_expired first for a clean list of live keys.

Source

pub fn ttl(&self) -> Duration

Return the configured time-to-live for cached results.

Source

pub fn max_entries(&self) -> Option<usize>

Return the configured maximum number of cached entries, if any.

Returns None if no cap was set via with_max_entries.

Source

pub fn is_idle(&self) -> Result<bool, AgentRuntimeError>

Return true if there are no in-flight requests.

Source

pub fn total_count(&self) -> Result<usize, AgentRuntimeError>

Return the total number of items tracked by the deduplicator (in-flight + cached results, regardless of TTL expiry).

Source

pub fn contains(&self, key: &str) -> Result<bool, AgentRuntimeError>

Return true if key is currently in-flight or has a cached result.

Unlike check_and_register this is a read-only inspection — it does not register the key or consume a deduplication slot.

Source

pub fn get_result(&self, key: &str) -> Result<Option<String>, AgentRuntimeError>

Return the cached result for key if one exists and has not expired.

Returns None when the key is not in the cache (either not yet completed or already expired). Does not modify any state.

Source

pub fn clear(&self) -> Result<(), AgentRuntimeError>

Remove all in-flight entries and cached results.

Useful for test teardown or hard resets.

Source

pub fn purge_expired(&self) -> Result<usize, AgentRuntimeError>

Eagerly evict all cache entries whose TTL has elapsed.

Under normal operation expired entries are removed lazily on the next check* call. Call purge_expired for deterministic memory reclamation (e.g. before a cached_count snapshot or in a maintenance loop).

Returns the number of entries that were removed.

Source

pub fn evict_oldest(&self) -> Result<bool, AgentRuntimeError>

Remove the oldest cached result entry (FIFO order).

Returns true if an entry was removed, false if the cache was empty.

Trait Implementations§

Source§

impl Clone for Deduplicator

Source§

fn clone(&self) -> Deduplicator

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for Deduplicator

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more