refactor: remove Mutex around rate limiter

Rate limiter handles all the necessary locking internally.
This commit is contained in:
link2xt
2026-01-26 17:59:12 +00:00
committed by l
parent 3be4c4d5ee
commit aa5999cc25
+5 -9
View File
@@ -10,12 +10,12 @@ use async_trait::async_trait;
use governor::{DefaultKeyedRateLimiter, Quota, RateLimiter}; use governor::{DefaultKeyedRateLimiter, Quota, RateLimiter};
use lettre::{AsyncSmtpTransport, AsyncTransport, Tokio1Executor}; use lettre::{AsyncSmtpTransport, AsyncTransport, Tokio1Executor};
use mailparse::{MailHeaderMap, parse_mail}; use mailparse::{MailHeaderMap, parse_mail};
use std::sync::{Arc, Mutex}; use std::sync::Arc;
/// Handler for outgoing SMTP messages. /// Handler for outgoing SMTP messages.
pub struct OutgoingBeforeQueueHandler { pub struct OutgoingBeforeQueueHandler {
config: Arc<Config>, config: Arc<Config>,
send_rate_limiter: Arc<Mutex<DefaultKeyedRateLimiter<String>>>, send_rate_limiter: DefaultKeyedRateLimiter<String>,
} }
impl OutgoingBeforeQueueHandler { impl OutgoingBeforeQueueHandler {
@@ -23,7 +23,7 @@ impl OutgoingBeforeQueueHandler {
let quota = Quota::per_minute(config.max_user_send_per_minute); let quota = Quota::per_minute(config.max_user_send_per_minute);
Self { Self {
config: Arc::new(config), config: Arc::new(config),
send_rate_limiter: Arc::new(Mutex::new(RateLimiter::keyed(quota))), send_rate_limiter: RateLimiter::keyed(quota),
} }
} }
} }
@@ -38,11 +38,7 @@ impl SmtpHandler for OutgoingBeforeQueueHandler {
return Err(format!("500 Invalid from address <{}>", address)); return Err(format!("500 Invalid from address <{}>", address));
} }
let Ok(limiter) = self.send_rate_limiter.lock() else { if let Err(e) = self.send_rate_limiter.check_key(&address.to_string()) {
log::error!("send_rate_limiter lock panicked!");
return Err("451 Temporary server error".to_string());
};
if let Err(e) = limiter.check_key(&address.to_string()) {
// "<example@example.org> rate limited until: ..." // "<example@example.org> rate limited until: ..."
log::debug!("<{address}> {e}"); log::debug!("<{address}> {e}");
return Err(format!("450 4.7.1: Too much mail from <{address}>, {e}")); return Err(format!("450 4.7.1: Too much mail from <{address}>, {e}"));
@@ -55,7 +51,7 @@ impl SmtpHandler for OutgoingBeforeQueueHandler {
// In the future, in case of higher traffic this can be further optimized by e.g. calling it // In the future, in case of higher traffic this can be further optimized by e.g. calling it
// every N messages or in a separate task every N minutes. // every N messages or in a separate task every N minutes.
// Time complexity is O(n) where n is the number of unique senders in the last minute. // Time complexity is O(n) where n is the number of unique senders in the last minute.
limiter.retain_recent(); self.send_rate_limiter.retain_recent();
Ok(()) Ok(())
} }