pub struct PerSenderTracker { /* private fields */ }Expand description
Per-sender sliding-window rate limiter.
Each unique sender key (Telegram thread ID, Discord channel, etc.) gets
its own independent ActionTracker bucket. When no sender is in scope
(cron jobs, CLI), the GLOBAL_KEY bucket is used.
The bucket map is shared via Arc so a SubAgent policy that clones
from its parent observes the same live counts. SubAgent budget
inheritance relies on this: a child run consuming an action sees the
shared bucket update, so the parent’s max_actions_per_hour ceiling
applies across both runs rather than each getting a fresh allocation.
Note: sender buckets accumulate for the daemon lifetime with no eviction. This is acceptable for bounded sets of chat IDs; in high-cardinality deployments, consider periodic cleanup.
Implementations§
Source§impl PerSenderTracker
impl PerSenderTracker
Sourcepub const GLOBAL_KEY: &'static str = "__global__"
pub const GLOBAL_KEY: &'static str = "__global__"
Bucket key used when no per-sender context is available (cron, CLI).
Sourcepub fn record_for_current(&self, max: u32) -> bool
pub fn record_for_current(&self, max: u32) -> bool
Record one action for the current sender. Returns true if allowed
(count after recording <= max), false if budget exhausted.
Sourcepub fn record_within(&self, key: &str, max: u32) -> bool
pub fn record_within(&self, key: &str, max: u32) -> bool
Record one action for key. Allows the action when count == max (≤ max);
blocks and returns false when count > max.
Sourcepub fn is_limited_for_current(&self, max: u32) -> bool
pub fn is_limited_for_current(&self, max: u32) -> bool
Check if the current sender is at or over the limit (without recording).
Sourcepub fn is_exhausted(&self, key: &str, max: u32) -> bool
pub fn is_exhausted(&self, key: &str, max: u32) -> bool
Check if key is at or over max (without recording).
Does NOT insert a bucket for unseen keys.
A max of 0 is always exhausted (zero budget means no actions allowed).
Returns true when count has reached or exceeded max. Note: acquires write lock
because ActionTracker::count prunes stale entries internally. Also note: returns
true one count earlier than record_within would block.
Trait Implementations§
Source§impl Clone for PerSenderTracker
impl Clone for PerSenderTracker
Source§fn clone(&self) -> Self
fn clone(&self) -> Self
Cloning a PerSenderTracker shares the bucket map by Arc.
SubAgent runs consume from the same buckets as their parent
so per-hour and per-day budgets are not bypassed by spawning
children. Tests that need an isolated tracker construct a
fresh one via Self::new rather than cloning.
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl Debug for PerSenderTracker
impl Debug for PerSenderTracker
Auto Trait Implementations§
impl Freeze for PerSenderTracker
impl !RefUnwindSafe for PerSenderTracker
impl Send for PerSenderTracker
impl Sync for PerSenderTracker
impl Unpin for PerSenderTracker
impl UnsafeUnpin for PerSenderTracker
impl !UnwindSafe for PerSenderTracker
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<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