pub struct InMemoryStore { /* private fields */ }Expand description
Single-node in-memory store: atomic counters behind a short transaction mutex that serializes check-and-spend so multi-key spends stay atomic.
Implementations§
Source§impl InMemoryStore
impl InMemoryStore
Trait Implementations§
Source§impl Debug for InMemoryStore
impl Debug for InMemoryStore
Source§impl Default for InMemoryStore
impl Default for InMemoryStore
Source§fn default() -> InMemoryStore
fn default() -> InMemoryStore
Source§impl StateStore for InMemoryStore
impl StateStore for InMemoryStore
Source§fn refund(&self, key: &str, amount: u64)
fn refund(&self, key: &str, amount: u64)
Round-33 F1: saturating refund. saturating_sub on i64 keeps
the value non-negative even under concurrent remove_prefix
or a duplicate refund; the transaction lock keeps the
load/store pair atomic with respect to other spend / add
operations on the same key.
Round-34 F1: NEVER resurrect a cell that a concurrent
remove_prefix already dropped. The prior implementation
used self.cell(key) which materialises a fresh 0
AtomicI64 in the DashMap via entry().or_insert_with(...).
Under the round-33 lost-claim-plus-idle-close ordering
(mcp_call’s sandbox-gate debit races with the reconciler’s
clear_budget_state), the refund path would create a
permanent 0-cell for a sealed session that no future
remove_prefix would ever collect — attacker-driven memory
growth. Skip the refund silently when the cell is gone;
the “budget spent” state is already whatever the caller
wanted (probably 0) and there’s nothing to compensate.
Source§fn add(&self, key: &str, delta: u64) -> Result<u64, StateError>
fn add(&self, key: &str, delta: u64) -> Result<u64, StateError>
delta to key, returning the new value.Source§fn get(&self, key: &str) -> Result<u64, StateError>
fn get(&self, key: &str) -> Result<u64, StateError>
key (0 if absent).Source§fn try_spend(
&self,
key: &str,
amount: u64,
limit: u64,
) -> Result<bool, StateError>
fn try_spend( &self, key: &str, amount: u64, limit: u64, ) -> Result<bool, StateError>
amount from the remaining budget limit - spent(key).
Returns Ok(true) and records the spend if the full amount fits,
Ok(false) (recording nothing) otherwise.Source§fn try_spend_many(&self, spends: &[Spend]) -> Result<Option<usize>, StateError>
fn try_spend_many(&self, spends: &[Spend]) -> Result<Option<usize>, StateError>
Source§fn remove_prefix(&self, prefix: &str)
fn remove_prefix(&self, prefix: &str)
prefix (whole-session cleanup at
finalization). Backends with native expiry (e.g. Redis TTLs) may
leave this as the default no-op; in-process backends must implement
it or session-keyed counters accumulate for the process lifetime.Auto Trait Implementations§
impl !Freeze for InMemoryStore
impl !RefUnwindSafe for InMemoryStore
impl Send for InMemoryStore
impl Sync for InMemoryStore
impl Unpin for InMemoryStore
impl UnsafeUnpin for InMemoryStore
impl UnwindSafe for InMemoryStore
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more