1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
//! The core Store seam and returned usage.
use ;
use RateLimitError;
/// The operating mode to use when the rate-limit store fails.
/// The usage and reset duration returned by a store.
/// An asynchronous fixed-window rate-limit store.
///
/// Implementations receive a complete, policy-scoped key and must treat it as opaque. For each
/// key, [`Store::increment`] must atomically create or increment one fixed window, start expiry on
/// the first increment, and leave that expiry unchanged on later increments. The returned
/// [`Usage`] includes the current increment, so `used` is at least one and `reset_after` is the
/// remaining duration of the active window.
///
/// Clones of one Store value must observe the same counter state. Independently constructed Store
/// values may use separate state. Backend failures are represented as [`RateLimitError::Store`].
///
/// This trait intentionally requires [`Clone`] because [`super::RateLimitLayer`] clones its Store
/// into each produced Service and [`super::RateLimit::call`](tower_service::Service::call) clones it
/// into each request's [`super::ResponseFuture`]. It does not require `Send`, `Sync`, or `'static`,
/// and its Future has no unconditional `Send + 'static` bound. Frameworks should add those
/// concurrency bounds at the integration point. For example, a generic Store passed to Axum's
/// `Router::layer` normally needs `S: Store + Send + Sync + 'static` and
/// `S::Future: Send + 'static` because Axum requires the resulting Layer, Service, and response
/// Future to satisfy those bounds.