Run Sieve scripts in async context

This commit is contained in:
mdecimus
2024-05-24 10:32:41 +02:00
parent ffdb7d766a
commit 4e7087d335
19 changed files with 363 additions and 458 deletions

View File

@@ -60,7 +60,6 @@ use self::throttle::{ThrottleKey, ThrottleKeyHasherBuilder};
pub mod params;
pub mod throttle;
pub mod worker;
#[derive(Clone)]
pub struct SmtpInstance {
@@ -95,7 +94,6 @@ pub struct SMTP {
}
pub struct Inner {
pub worker_pool: rayon::ThreadPool,
pub session_throttle: DashMap<ThrottleKey, ConcurrencyLimiter, ThrottleKeyHasherBuilder>,
pub queue_throttle: DashMap<ThrottleKey, ConcurrencyLimiter, ThrottleKeyHasherBuilder>,
pub queue_tx: mpsc::Sender<queue::Event>,
@@ -431,10 +429,6 @@ impl SessionAddress {
impl Default for Inner {
fn default() -> Self {
Self {
worker_pool: rayon::ThreadPoolBuilder::new()
.num_threads(num_cpus::get())
.build()
.unwrap(),
session_throttle: Default::default(),
queue_throttle: Default::default(),
queue_tx: mpsc::channel(1).0,

View File

@@ -29,9 +29,12 @@ use common::{
use dashmap::mapref::entry::Entry;
use utils::config::Rate;
use std::hash::{BuildHasher, Hash, Hasher};
use std::{
hash::{BuildHasher, Hash, Hasher},
sync::atomic::Ordering,
};
use super::Session;
use super::{Session, SMTP};
#[derive(Debug, Clone, Eq)]
pub struct ThrottleKey {
@@ -318,3 +321,11 @@ impl<T: SessionStream> Session<T> {
.is_none()
}
}
impl SMTP {
pub fn cleanup(&self) {
for throttle in [&self.inner.session_throttle, &self.inner.queue_throttle] {
throttle.retain(|_, v| v.concurrent.load(Ordering::Relaxed) > 0);
}
}
}

View File

@@ -1,69 +0,0 @@
/*
* Copyright (c) 2023 Stalwart Labs Ltd.
*
* This file is part of Stalwart Mail Server.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
* in the LICENSE file at the top-level directory of this distribution.
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* You can be released from the requirements of the AGPLv3 license by
* purchasing a commercial license. Please contact licensing@stalw.art
* for more details.
*/
use std::sync::atomic::Ordering;
use tokio::sync::oneshot;
use super::SMTP;
impl SMTP {
pub async fn spawn_worker<U, V>(&self, f: U) -> Option<V>
where
U: FnOnce() -> V + Send,
V: Sync + Send + 'static,
{
let (tx, rx) = oneshot::channel();
self.inner.worker_pool.scope(|s| {
s.spawn(|_| {
tx.send(f()).ok();
});
});
match rx.await {
Ok(result) => Some(result),
Err(err) => {
tracing::warn!(
context = "worker-pool",
event = "error",
reason = %err,
);
None
}
}
}
fn cleanup(&self) {
for throttle in [&self.inner.session_throttle, &self.inner.queue_throttle] {
throttle.retain(|_, v| v.concurrent.load(Ordering::Relaxed) > 0);
}
}
pub fn spawn_cleanup(&self) {
let core = self.clone();
self.inner.worker_pool.spawn(move || {
core.cleanup();
});
}
}