mirror of
https://github.com/chatmail/relay.git
synced 2026-09-17 21:00:13 +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 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(())
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user