pub struct HybridRateLimiter { /* private fields */ }Expand description
Hybrid rate limiter with in-memory fast path and periodic DB sync.
Per-user/per-IP checks use a local DashMap for sub-microsecond decisions,
so a 100 req/min limit becomes 100 × N across an N-node cluster. Right
for DDoS protection where the threshold is approximate. For cluster-wide
correctness (e.g. billing quotas) use StrictRateLimiter.
Global keys always hit the database for cross-node consistency.
DESIGN: Per-node rate limiting. Cluster-wide consistency trades latency for accuracy. With N nodes, effective limit is N× per-key. Keep per-node budgets low.
Implementations§
Source§impl HybridRateLimiter
impl HybridRateLimiter
pub fn new(pool: PgPool) -> Self
Sourcepub fn with_max_buckets(pool: PgPool, max_local_buckets: usize) -> Self
pub fn with_max_buckets(pool: PgPool, max_local_buckets: usize) -> Self
Create a hybrid rate limiter with a custom local bucket limit.
pub async fn check( &self, bucket_key: &str, config: &RateLimitConfig, ) -> Result<RateLimitResult>
pub fn build_key( &self, key_type: RateLimitKey, action_name: &str, auth: &AuthContext, request: &RequestMetadata, ) -> String
pub async fn enforce( &self, bucket_key: &str, config: &RateLimitConfig, ) -> Result<RateLimitResult>
Sourcepub fn cleanup_local(&self, max_idle: Duration)
pub fn cleanup_local(&self, max_idle: Duration)
Clean up expired local buckets (call periodically).
Trait Implementations§
Source§impl RateLimiterBackend for HybridRateLimiter
impl RateLimiterBackend for HybridRateLimiter
Source§fn check<'a>(
&'a self,
bucket_key: &'a str,
config: &'a RateLimitConfig,
) -> Pin<Box<dyn Future<Output = Result<RateLimitResult>> + Send + 'a>>
fn check<'a>( &'a self, bucket_key: &'a str, config: &'a RateLimitConfig, ) -> Pin<Box<dyn Future<Output = Result<RateLimitResult>> + Send + 'a>>
Check whether a single token is available for the given bucket.
Source§fn build_key(
&self,
key_type: RateLimitKey,
action_name: &str,
auth: &AuthContext,
request: &RequestMetadata,
) -> String
fn build_key( &self, key_type: RateLimitKey, action_name: &str, auth: &AuthContext, request: &RequestMetadata, ) -> String
Build the bucket key string for a (key kind, action, auth, request) tuple.
Source§fn enforce<'a>(
&'a self,
bucket_key: &'a str,
config: &'a RateLimitConfig,
) -> Pin<Box<dyn Future<Output = Result<RateLimitResult>> + Send + 'a>>
fn enforce<'a>( &'a self, bucket_key: &'a str, config: &'a RateLimitConfig, ) -> Pin<Box<dyn Future<Output = Result<RateLimitResult>> + Send + 'a>>
Check and convert a denial into a
ForgeError::RateLimitExceeded.Auto Trait Implementations§
impl Freeze for HybridRateLimiter
impl !RefUnwindSafe for HybridRateLimiter
impl Send for HybridRateLimiter
impl Sync for HybridRateLimiter
impl Unpin for HybridRateLimiter
impl UnsafeUnpin for HybridRateLimiter
impl !UnwindSafe for HybridRateLimiter
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
Mutably borrows from an owned value. Read more
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§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>
Converts
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>
Converts
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