pub struct Eviction { /* private fields */ }Expand description
How the limiter bounds the memory its per-key state can occupy.
A rate limiter that tracks state per key is a denial-of-service vector
against itself if that state can grow without limit: a flood of unique keys
would exhaust memory. Eviction is the defense. Two independent bounds
compose:
- Capacity — a hard ceiling on the number of live keys. When inserting a new key would exceed it, the least-recently-seen key is evicted. This is what caps a unique-key flood.
- Idle TTL — keys not seen for longer than the TTL become evictable, so long-idle state is reclaimed rather than held forever.
Eviction is lazy and incremental: it happens while inserting a new key, touches only the one shard being written, and never sweeps the whole store or blocks the steady-state check path. The capacity is enforced approximately per shard, so the live-key count stays within a small factor of the cap.
The Default is safe: a DEFAULT_MAX_KEYS capacity cap and no TTL —
memory is bounded out of the box. Opt into unbounded growth explicitly with
unbounded, understanding the risk.
§Examples
use rate_net::Eviction;
use std::time::Duration;
// Cap at 100k keys and reclaim anything idle for five minutes.
let policy = Eviction::capacity(100_000).with_idle(Duration::from_secs(300));
assert_eq!(policy.max_keys(), Some(100_000));
assert_eq!(policy.idle_ttl(), Some(Duration::from_secs(300)));Implementations§
Source§impl Eviction
impl Eviction
Sourcepub const fn capacity(max_keys: usize) -> Self
pub const fn capacity(max_keys: usize) -> Self
A hard cap of max_keys live keys, with no idle expiry.
A max_keys of 0 is treated as 1 (the store always holds at least
one key per shard).
§Examples
use rate_net::Eviction;
let policy = Eviction::capacity(50_000);
assert_eq!(policy.max_keys(), Some(50_000));
assert_eq!(policy.idle_ttl(), None);Sourcepub const fn idle(ttl: Duration) -> Self
pub const fn idle(ttl: Duration) -> Self
Reclaim keys idle for longer than ttl, keeping the default capacity cap.
Idle expiry alone does not bound a unique-key flood — flooded keys are not
idle — so this keeps the DEFAULT_MAX_KEYS cap as the flood defense and
layers the TTL on top. Use capacity plus
with_idle to choose both bounds explicitly.
§Examples
use rate_net::{Eviction, DEFAULT_MAX_KEYS};
use std::time::Duration;
let policy = Eviction::idle(Duration::from_secs(300));
assert_eq!(policy.idle_ttl(), Some(Duration::from_secs(300)));
assert_eq!(policy.max_keys(), Some(DEFAULT_MAX_KEYS));Sourcepub const fn new(max_keys: usize, ttl: Duration) -> Self
pub const fn new(max_keys: usize, ttl: Duration) -> Self
Both bounds at once: a max_keys cap and an idle ttl.
§Examples
use rate_net::Eviction;
use std::time::Duration;
let policy = Eviction::new(10_000, Duration::from_secs(60));
assert_eq!(policy.max_keys(), Some(10_000));
assert_eq!(policy.idle_ttl(), Some(Duration::from_secs(60)));Sourcepub const fn unbounded() -> Self
pub const fn unbounded() -> Self
No bounds at all — the store grows without limit.
Only safe when the key space is intrinsically bounded (a fixed set of
tenants, say). Against untrusted keys this is a self-inflicted
denial-of-service: prefer capacity.
§Examples
use rate_net::Eviction;
let policy = Eviction::unbounded();
assert_eq!(policy.max_keys(), None);
assert_eq!(policy.idle_ttl(), None);Sourcepub const fn with_capacity(self, max_keys: usize) -> Self
pub const fn with_capacity(self, max_keys: usize) -> Self
Returns a copy with the capacity cap set to max_keys.
§Examples
use rate_net::Eviction;
use std::time::Duration;
let policy = Eviction::idle(Duration::from_secs(30)).with_capacity(1_000);
assert_eq!(policy.max_keys(), Some(1_000));Sourcepub const fn with_idle(self, ttl: Duration) -> Self
pub const fn with_idle(self, ttl: Duration) -> Self
Returns a copy with idle expiry set to ttl.
§Examples
use rate_net::Eviction;
use std::time::Duration;
let policy = Eviction::capacity(1_000).with_idle(Duration::from_secs(30));
assert_eq!(policy.idle_ttl(), Some(Duration::from_secs(30)));Sourcepub const fn without_capacity(self) -> Self
pub const fn without_capacity(self) -> Self
Returns a copy with the capacity cap removed (unbounded key count).
§Examples
use rate_net::Eviction;
let policy = Eviction::default().without_capacity();
assert_eq!(policy.max_keys(), None);Trait Implementations§
Source§impl Default for Eviction
impl Default for Eviction
Source§fn default() -> Self
fn default() -> Self
A DEFAULT_MAX_KEYS capacity cap and no idle TTL — bounded memory out
of the box.