性能优化

This commit is contained in:
zhongluofeng
2026-08-06 10:33:16 +08:00
parent c7578a2e6b
commit e66c53e66d
105 changed files with 7273 additions and 5002 deletions
+62 -1
View File
@@ -38,7 +38,7 @@ impl RateLimiter {
// 尝试在当前窗口消费(用作用域确保 MutexGuard 在 await 前释放)
let over_limit = {
let now = std::time::Instant::now();
let mut start = self.window_start.lock().unwrap();
let mut start = self.window_start.lock().unwrap_or_else(|e| e.into_inner());
let elapsed = now.duration_since(*start);
// 窗口过期,重置
@@ -72,3 +72,64 @@ impl Clone for RateLimiter {
Self::new(self.limit.load(Ordering::Relaxed))
}
}
#[cfg(test)]
mod rate_limiter_tests {
use super::*;
use std::time::Instant;
#[tokio::test]
async fn zero_limit_never_blocks() {
let limiter = RateLimiter::new(0);
let start = Instant::now();
limiter.consume(1024 * 1024).await;
limiter.consume(u64::MAX).await;
assert!(start.elapsed() < Duration::from_millis(50));
}
#[tokio::test]
async fn under_limit_returns_immediately() {
let limiter = RateLimiter::new(100_000); // 100KB/s
let start = Instant::now();
limiter.consume(1024).await;
assert!(start.elapsed() < Duration::from_millis(50));
}
#[tokio::test]
async fn exceeding_limit_waits_proportionally() {
// 限速 200 B/s:先消耗 100 未超限,再消耗 150 → 超限 50 → 等待约 250ms
let limiter = RateLimiter::new(200);
limiter.consume(100).await;
let start = Instant::now();
limiter.consume(150).await;
let elapsed = start.elapsed();
assert!(
elapsed >= Duration::from_millis(200),
"等待时间不足: {:?}",
elapsed
);
assert!(elapsed < Duration::from_millis(1100));
}
#[tokio::test]
async fn window_resets_after_one_second() {
// 限速 100 B/s:第一窗口耗尽后,1.1s 窗口重置,再消耗 100 不应阻塞
let limiter = RateLimiter::new(100);
limiter.consume(100).await;
tokio::time::sleep(Duration::from_millis(1100)).await;
let start = Instant::now();
limiter.consume(100).await;
assert!(start.elapsed() < Duration::from_millis(100));
}
#[tokio::test]
async fn set_limit_takes_effect_dynamically() {
let limiter = RateLimiter::new(0);
limiter.consume(1024).await; // 不限速
limiter.set_limit(100);
limiter.consume(100).await;
let start = Instant::now();
limiter.consume(100).await; // 累计 200 > 100 → 等待 1000ms
assert!(start.elapsed() >= Duration::from_millis(900));
}
}