rate-limiter: re-validate burst window in loop after sleep

Signed-off-by: NotAShelf <raf@notashelf.dev>
Change-Id: Iaa63eef1f055b9a98c90739025bd3ff36a6a6964
This commit is contained in:
raf 2026-02-21 19:50:55 +03:00
commit 5a7762ac13
Signed by: NotAShelf
GPG key ID: 29D95B64378DB4BF

View file

@ -72,32 +72,29 @@ impl RateLimiter {
let interval = Duration::from_secs(60) / rate.max(1); let interval = Duration::from_secs(60) / rate.max(1);
let mut inner = self.inner.lock().await; loop {
let now = Instant::now(); let mut inner = self.inner.lock().await;
let platform_requests = let now = Instant::now();
inner.requests.entry(platform.to_string()).or_default(); let platform_requests =
inner.requests.entry(platform.to_string()).or_default();
platform_requests platform_requests
.retain(|t| now.duration_since(*t) < Duration::from_secs(60)); .retain(|t| now.duration_since(*t) < Duration::from_secs(60));
if platform_requests.len() >= burst as usize if platform_requests.len() >= burst as usize
&& let Some(oldest) = platform_requests.first() && let Some(oldest) = platform_requests.first()
{ {
let wait_time = interval.saturating_sub(now.duration_since(*oldest)); let wait_time = interval.saturating_sub(now.duration_since(*oldest));
if wait_time > Duration::ZERO { if wait_time > Duration::ZERO {
drop(inner); drop(inner);
tokio::time::sleep(wait_time).await; tokio::time::sleep(wait_time).await;
let mut inner = self.inner.lock().await; continue;
let platform_requests = }
inner.requests.entry(platform.to_string()).or_default();
platform_requests.push(Instant::now());
return Ok(());
} }
platform_requests.push(Instant::now());
return Ok(());
} }
platform_requests.push(Instant::now());
Ok(())
} }
pub async fn wait_for(&self, platform: &str) { pub async fn wait_for(&self, platform: &str) {