mirror of
https://github.com/chatmail/relay.git
synced 2026-08-12 03:20:51 +00:00
refactor: remove Mutex around rate limiter
Rate limiter handles all the necessary locking internally.
This commit is contained in:
@@ -10,12 +10,12 @@ use async_trait::async_trait;
|
||||
use governor::{DefaultKeyedRateLimiter, Quota, RateLimiter};
|
||||
use lettre::{AsyncSmtpTransport, AsyncTransport, Tokio1Executor};
|
||||
use mailparse::{MailHeaderMap, parse_mail};
|
||||
use std::sync::{Arc, Mutex};
|
||||
use std::sync::Arc;
|
||||
|
||||
/// Handler for outgoing SMTP messages.
|
||||
pub struct OutgoingBeforeQueueHandler {
|
||||
config: Arc<Config>,
|
||||
send_rate_limiter: Arc<Mutex<DefaultKeyedRateLimiter<String>>>,
|
||||
send_rate_limiter: DefaultKeyedRateLimiter<String>,
|
||||
}
|
||||
|
||||
impl OutgoingBeforeQueueHandler {
|
||||
@@ -23,7 +23,7 @@ impl OutgoingBeforeQueueHandler {
|
||||
let quota = Quota::per_minute(config.max_user_send_per_minute);
|
||||
Self {
|
||||
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));
|
||||
}
|
||||
|
||||
let Ok(limiter) = self.send_rate_limiter.lock() else {
|
||||
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()) {
|
||||
if let Err(e) = self.send_rate_limiter.check_key(&address.to_string()) {
|
||||
// "<example@example.org> rate limited until: ..."
|
||||
log::debug!("<{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
|
||||
// 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.
|
||||
limiter.retain_recent();
|
||||
self.send_rate_limiter.retain_recent();
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user