···12 sync::{Arc, LazyLock},
13 time::Duration,
14};
01516static CLOCK: LazyLock<DefaultClock> = LazyLock::new(DefaultClock::default);
17···70/// Once the rate limit has been reached, the middleware will respond with
71/// status code 429 (too many requests) and a `Retry-After` header with the amount
72/// of time that needs to pass before another request will be allowed.
73-#[derive(Debug, Clone)]
74pub struct GovernorMiddleware {
0075 limiters: Arc<IpLimiters>,
76}
7778impl GovernorMiddleware {
000079 pub fn new(quota: Quota) -> Self {
000000000000000000000080 Self {
81- limiters: Arc::new(IpLimiters::new(quota)),
082 }
83 }
84}
···12 sync::{Arc, LazyLock},
13 time::Duration,
14};
15+use tokio::sync::oneshot;
1617static CLOCK: LazyLock<DefaultClock> = LazyLock::new(DefaultClock::default);
18···71/// Once the rate limit has been reached, the middleware will respond with
72/// status code 429 (too many requests) and a `Retry-After` header with the amount
73/// of time that needs to pass before another request will be allowed.
74+#[derive(Debug)]
75pub struct GovernorMiddleware {
76+ #[allow(dead_code)]
77+ stop_on_drop: oneshot::Sender<()>,
78 limiters: Arc<IpLimiters>,
79}
8081impl GovernorMiddleware {
82+ /// Limit request rates
83+ ///
84+ /// a little gross but this spawns a tokio task for housekeeping:
85+ /// https://docs.rs/governor/latest/governor/struct.RateLimiter.html#keyed-rate-limiters---housekeeping
86 pub fn new(quota: Quota) -> Self {
87+ let limiters = Arc::new(IpLimiters::new(quota));
88+ let (stop_on_drop, mut stopped) = oneshot::channel();
89+ tokio::task::spawn({
90+ let limiters = limiters.clone();
91+ async move {
92+ loop {
93+ tokio::select! {
94+ _ = &mut stopped => break,
95+ _ = tokio::time::sleep(Duration::from_secs(60)) => {},
96+ };
97+ log::debug!(
98+ "limiter sizes before housekeeping: {}/ip {}/v6_56 {}/v6_48",
99+ limiters.per_ip.len(),
100+ limiters.ip6_56.len(),
101+ limiters.ip6_48.len(),
102+ );
103+ limiters.per_ip.retain_recent();
104+ limiters.ip6_56.retain_recent();
105+ limiters.ip6_48.retain_recent();
106+ }
107+ }
108+ });
109 Self {
110+ stop_on_drop,
111+ limiters,
112 }
113 }
114}