我试图使用Governor crate让Warp中的速率限制工作。然而,当我尝试在闭包的Arc
部分内使用rate_limiter实例时,我一直收到“预期闭包实现了Fn
trait,但这个闭包仅实现了FnOnce
”的错误信息。
我已经尝试在闭包内外克隆rate_limiter实例,但仍然报错。有人能帮我解决这个问题吗?
use crate::rejections::RateLimitFailure;
use dashmap::DashMap;
use governor::{
clock::{QuantaClock, QuantaInstant},
middleware::NoOpMiddleware,
state::InMemoryState,
Quota, RateLimiter,
};
use nonzero_ext::nonzero;
use std::collections::hash_map::RandomState;
use std::sync::Arc;
use warp::{Filter, Rejection};
const LIMIT: u32 = 50;
#[derive(Debug, Clone)]
pub struct FridayRateLimiter<'a> {
pub lim: Arc<
RateLimiter<
&'a str,
DashMap<&'a str, InMemoryState, RandomState>,
QuantaClock,
NoOpMiddleware<QuantaInstant>,
>,
>,
}
impl<'a> FridayRateLimiter<'a> {
pub fn new() -> Self {
let lim = Arc::new(RateLimiter::keyed(Quota::per_second(nonzero!(LIMIT))));
FridayRateLimiter { lim }
}
}
pub fn with_rate_limiter(
rate_limiter: FridayRateLimiter,
) -> impl Filter<Extract = (bool,), Error = Rejection> + Clone {
let addr = warp::header::<String>("HTTP_X_FORWARDED_FOR");
let rate_limiter = rate_limiter.clone();
addr.and_then(|ip: String| async move {
let rate_limiter = rate_limiter.clone();
if rate_limiter.lim.check_key(&ip.as_str()).is_err() {
return Err(warp::reject::custom(RateLimitFailure));
}
Ok(true)
})
}
FnOnce
,而不是Fn
| | | 实现Fn
的要求源自此处 42 | let rate_limiter = rate_limiter.clone(); | ------------ 闭包是FnOnce
,因为它将变量rate_limiter
移出其环境 | = 注意:需要[closure@src/rate_limiter.rs:41:19: 41:31]
实现warp::generic::Func<(std::string::String,)>
- Bhargav