use std::sync::{Arc, Mutex, OnceLock};
use std::thread;
use std::time::Duration;
#[derive(Debug, Clone)]
pub struct ThreadPoolConfig {
pub num_threads: usize,
pub stack_size: Option<usize>,
pub thread_name: Option<String>,
pub idle_timeout: Option<Duration>,
pub max_chunk_size: Option<usize>,
pub min_chunk_size: Option<usize>,
}
impl Default for ThreadPoolConfig {
fn default() -> Self {
Self {
num_threads: thread::available_parallelism()
.map(|n| n.get())
.unwrap_or(1),
stack_size: None,
thread_name: Some("avila-worker".to_string()),
idle_timeout: None,
max_chunk_size: None,
min_chunk_size: Some(1024),
}
}
}
impl ThreadPoolConfig {
pub fn new() -> Self {
Self::default()
}
pub fn num_threads(mut self, n: usize) -> Self {
self.num_threads = n;
self
}
pub fn stack_size(mut self, size: usize) -> Self {
self.stack_size = Some(size);
self
}
pub fn thread_name(mut self, name: impl Into<String>) -> Self {
self.thread_name = Some(name.into());
self
}
pub fn idle_timeout(mut self, timeout: Duration) -> Self {
self.idle_timeout = Some(timeout);
self
}
pub fn max_chunk_size(mut self, size: usize) -> Self {
self.max_chunk_size = Some(size);
self
}
pub fn min_chunk_size(mut self, size: usize) -> Self {
self.min_chunk_size = Some(size);
self
}
pub fn effective_min_chunk_size(&self) -> usize {
self.min_chunk_size.unwrap_or(1024)
}
}
static CONFIG: OnceLock<Arc<Mutex<ThreadPoolConfig>>> = OnceLock::new();
fn get_config_lock() -> &'static Arc<Mutex<ThreadPoolConfig>> {
CONFIG.get_or_init(|| {
Arc::new(Mutex::new(ThreadPoolConfig::default()))
})
}
pub fn set_global_config(config: ThreadPoolConfig) {
*get_config_lock().lock().unwrap() = config;
}
pub fn get_global_config() -> ThreadPoolConfig {
get_config_lock().lock().unwrap().clone()
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_config_builder() {
let config = ThreadPoolConfig::new()
.num_threads(4)
.stack_size(2 * 1024 * 1024)
.thread_name("test-worker")
.min_chunk_size(2048);
assert_eq!(config.num_threads, 4);
assert_eq!(config.stack_size, Some(2 * 1024 * 1024));
assert_eq!(config.thread_name, Some("test-worker".to_string()));
assert_eq!(config.min_chunk_size, Some(2048));
}
#[test]
fn test_default_config() {
let config = ThreadPoolConfig::default();
assert!(config.num_threads > 0);
assert_eq!(config.min_chunk_size, Some(1024));
}
}