mirror of
https://github.com/chatmail/relay.git
synced 2026-08-22 00:03:14 +00:00
fix: switch ratelimiter to MonotonicClock (#167)
There is a known bug that `quanta` clock used by default sometimes jumps back: <https://github.com/metrics-rs/quanta/issues/111>. This results in `governor` rate limiter incorrectly rejecting the messages even when less than the configured burst size has been sent. Switched to standard monotonic clock which does not have this problem. I tested that this fixed the problem for me, chatmail relay test `test_exceed_rate_limit` stopped failing randomly. Fixes <https://github.com/chatmail/filtermail/issues/166>
This commit is contained in:
@@ -8,7 +8,9 @@ pub use crate::smtp_server::Envelope;
|
||||
use crate::smtp_server::SmtpHandler;
|
||||
use crate::utils::{build_resolver, extract_address};
|
||||
use async_trait::async_trait;
|
||||
use governor::{DefaultKeyedRateLimiter, Quota, RateLimiter};
|
||||
use governor::clock::MonotonicClock;
|
||||
use governor::middleware::NoOpMiddleware;
|
||||
use governor::{Quota, RateLimiter};
|
||||
use hickory_resolver::TokioResolver;
|
||||
use mailparse::{MailHeaderMap, parse_mail};
|
||||
use std::sync::Arc;
|
||||
@@ -17,7 +19,20 @@ use std::sync::Arc;
|
||||
pub struct OutgoingBeforeQueueHandler {
|
||||
config: Config,
|
||||
dns_resolver: Arc<TokioResolver>,
|
||||
send_rate_limiter: DefaultKeyedRateLimiter<String>,
|
||||
|
||||
// We explicitly use standard MonotonicClock here.
|
||||
// governor 0.10.4 by default uses "quanta" clock
|
||||
// if the feature "quanta" is enabled
|
||||
// and it has a known problem
|
||||
// of sometimes jumping back in time
|
||||
// when moved between CPU cores:
|
||||
// <https://github.com/metrics-rs/quanta/issues/111>
|
||||
send_rate_limiter: RateLimiter<
|
||||
String,
|
||||
governor::state::keyed::DashMapStateStore<String>,
|
||||
MonotonicClock,
|
||||
NoOpMiddleware<std::time::Instant>,
|
||||
>,
|
||||
smtp_connection_pool: Arc<SmtpConnectionPool>,
|
||||
}
|
||||
|
||||
@@ -26,10 +41,11 @@ impl OutgoingBeforeQueueHandler {
|
||||
let quota = Quota::per_minute(config.max_user_send_per_minute)
|
||||
.allow_burst(config.max_user_send_burst_size);
|
||||
let dns_resolver = Arc::new(build_resolver()?);
|
||||
let send_rate_limiter = RateLimiter::dashmap_with_clock(quota, MonotonicClock);
|
||||
Ok(Self {
|
||||
config,
|
||||
dns_resolver,
|
||||
send_rate_limiter: RateLimiter::keyed(quota),
|
||||
send_rate_limiter,
|
||||
smtp_connection_pool: SmtpConnectionPool::new(),
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user