Skip to content

Commit 28285e1

Browse files
authored
Merge branch 'main' into feature/configs
2 parents ad04a87 + a806aeb commit 28285e1

3 files changed

Lines changed: 55 additions & 26 deletions

File tree

volga-rate-limiter/README.md

Lines changed: 52 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22

33
A lightweight and efficient rate-limiting library for Rust.
44

5-
This crate provides in-memory rate limiting algorithms designed
6-
for high-performance HTTP services and middleware.
5+
This crate provides rate limiting algorithms with pluggable storage backends,
6+
designed for high-performance HTTP services and middleware.
77

88
## Overview
99

@@ -16,10 +16,6 @@ Typical use cases include:
1616
- Applying different limits for anonymous users, authenticated users,
1717
tenants, or API keys
1818

19-
This crate focuses on **per-node, in-memory** rate limiting.
20-
It is intentionally simple and fast, and does **not** attempt to
21-
synchronize state across multiple processes or machines.
22-
2319
## Algorithms
2420

2521
The following rate-limiting algorithms are provided:
@@ -33,7 +29,7 @@ The following rate-limiting algorithms are provided:
3329
- Uses a sliding time window with linear weighting
3430
- Provides smoother request distribution
3531
- Slightly more expensive than a fixed window
36-
32+
3733
- `TokenBucketRateLimiter`
3834
- Allows bursts up to a token bucket capacity
3935
- Enforces a steady average refill rate
@@ -44,16 +40,62 @@ The following rate-limiting algorithms are provided:
4440
- Smooths traffic with explicit burst tolerance
4541
- Accurate average rate enforcement
4642

43+
## Pluggable Storage Backends
44+
45+
Each algorithm is generic over a **store trait**, allowing you to swap the
46+
default in-memory backend for an external one (e.g. Redis) without changing
47+
the rate limiting logic.
48+
49+
| Algorithm | Store trait | Operation |
50+
|---|---|---|
51+
| Fixed Window | `FixedWindowStore` | `check_and_count` |
52+
| Sliding Window | `SlidingWindowStore` | `check_and_count` |
53+
| Token Bucket | `TokenBucketStore` | `try_consume` |
54+
| GCRA | `GcraStore` | `check_and_advance` |
55+
56+
Each rate limiter provides constructors for all combinations:
57+
58+
- `::new()` — system clock + default in-memory store
59+
- `::with_time_source()` — custom clock + in-memory store
60+
- `::with_store()` — system clock + custom store
61+
- `::with_time_source_and_store()` — both custom
62+
63+
The default in-memory stores are backed by `DashMap` and use lock-free
64+
atomic operations on the hot path.
65+
66+
### Implementing a custom store
67+
68+
Store traits require a single atomic operation. Parameter structs are
69+
`#[non_exhaustive]` for forward compatibility — access fields by name:
70+
71+
```rust
72+
use volga_rate_limiter::store::{TokenBucketParams, TokenBucketStore};
73+
74+
struct MyRedisStore { /* ... */ }
75+
76+
impl TokenBucketStore for MyRedisStore {
77+
fn try_consume(&self, params: TokenBucketParams) -> bool {
78+
let key = params.key;
79+
let capacity = params.capacity_scaled;
80+
// ... your Redis logic here
81+
true
82+
}
83+
}
84+
```
85+
86+
> **Note:** Backends with built-in TTL support (like Redis) can skip manual
87+
> eviction — the eviction grace parameters are designed for in-memory stores
88+
> that perform lazy cleanup.
4789
4890
## Time Source Abstraction
4991

50-
All rate limiters are built on top of a pluggable [`TimeSource`] abstraction.
92+
All rate limiters are built on top of a pluggable `TimeSource` abstraction.
5193
This allows:
5294

5395
- Deterministic and fast unit testing
5496
- Custom time implementations if needed
5597

56-
The default implementation, [`SystemTimeSource`], is based on
98+
The default implementation, `SystemTimeSource`, is based on
5799
`std::time::Instant`.
58100

59101
## Concurrency Model
@@ -67,17 +109,10 @@ The rate limiters are designed to be:
67109
Internal state is optimized for frequent reads and updates under
68110
high contention.
69111

70-
## Scope and Limitations
71-
72-
- This crate implements **in-memory** rate limiting only
73-
- It does **not** provide distributed coordination
74-
- For multi-node systems, rate limiting should be combined with
75-
external storage or coordination mechanisms (e.g. Redis, gateways)
76-
77112
## Usage
78113

79114
The rate limiters are intended to be embedded into higher-level
80115
frameworks or middleware layers.
81116

82117
## License
83-
Volga is licensed under the MIT License. Contributions welcome!
118+
Volga is licensed under the MIT License. Contributions welcome!

volga-rate-limiter/src/lib.rs

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -66,13 +66,6 @@
6666
//! Internal state is optimized for frequent reads and updates under
6767
//! high contention.
6868
//!
69-
//! ## Scope and Limitations
70-
//!
71-
//! - This crate implements **in-memory** rate limiting only
72-
//! - It does **not** provide distributed coordination
73-
//! - For multi-node systems, rate limiting should be combined with
74-
//! external storage or coordination mechanisms (e.g. Redis, gateways)
75-
//!
7669
//! ## Usage
7770
//!
7871
//! The rate limiters are intended to be embedded into higher-level

volga/src/rate_limiting.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,9 @@ pub use sliding_window::SlidingWindow;
2727
pub use token_bucket::TokenBucket;
2828

2929
pub use volga_rate_limiter::{
30-
FixedWindowRateLimiter, GcraRateLimiter, RateLimiter, SlidingWindowRateLimiter,
31-
TokenBucketRateLimiter,
30+
FixedWindowParams, FixedWindowRateLimiter, FixedWindowStore, GcraParams, GcraRateLimiter,
31+
GcraStore, RateLimiter, SlidingWindowParams, SlidingWindowRateLimiter, SlidingWindowStore,
32+
TokenBucketParams, TokenBucketRateLimiter, TokenBucketStore,
3233
};
3334

3435
pub mod by;

0 commit comments

Comments
 (0)