pub enum TrySpendOutcome {
Committed {
post_commit_min_remaining: u64,
},
Refused {
index: usize,
},
}Expand description
Outcome of an atomic multi-dimensional spend. Carries the post- commit min-headroom across the spent keys on success — a value that CANNOT race with a concurrent spend/refund because it is computed inside the same atomic Lua (RedisStore) / mutex-critical section (InMemoryStore) that commits the spend.
Introduced in R68 to close R66 F3: the previous shape returned
Result<Option<usize>, StateError> (None = committed), forcing
downstream remaining_min code to issue a SECOND set of GET
round-trips to compute the reported headroom. Between the atomic
spend and those GETs, a concurrent remove_prefix could DEL the
counter — the GET returns 0, remaining = cap.saturating_sub(0)
reports the full budget as available immediately after a debit
that WAS committed. BudgetDecision::Allowed { remaining } is
used as a flow-control signal (routes.rs, pipeline.rs), so wrong
values reshape tail behaviour: bursts allowed through when they
should be paced, or requests refused when they should be
admitted. Not a security bug (the spend itself was atomic and
cap-checked); a correctness bug on the “remaining headroom” API
contract.
Variants§
Committed
All spends committed atomically. post_commit_min_remaining
= min over spends of spend.limit - post_commit_counter(spend.key),
where the post-commit counter is the value the same atomic
section wrote. u64::MAX for an empty spends slice.
Fields
Refused
The index-th spend would have exceeded its limit; nothing
was committed.
Trait Implementations§
Source§impl Clone for TrySpendOutcome
impl Clone for TrySpendOutcome
Source§fn clone(&self) -> TrySpendOutcome
fn clone(&self) -> TrySpendOutcome
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl Debug for TrySpendOutcome
impl Debug for TrySpendOutcome
Source§impl PartialEq for TrySpendOutcome
impl PartialEq for TrySpendOutcome
Source§fn eq(&self, other: &TrySpendOutcome) -> bool
fn eq(&self, other: &TrySpendOutcome) -> bool
self and other values to be equal, and is used by ==.impl Eq for TrySpendOutcome
impl StructuralPartialEq for TrySpendOutcome
Auto Trait Implementations§
impl Freeze for TrySpendOutcome
impl RefUnwindSafe for TrySpendOutcome
impl Send for TrySpendOutcome
impl Sync for TrySpendOutcome
impl Unpin for TrySpendOutcome
impl UnsafeUnpin for TrySpendOutcome
impl UnwindSafe for TrySpendOutcome
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
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key and return true if they are equal.§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