avila_parallel/
config.rs

1//! Custom thread pool configuration
2//!
3//! This module provides advanced configuration options for thread pools
4
5use std::sync::{Arc, Mutex, OnceLock};
6use std::thread;
7use std::time::Duration;
8
9/// Thread pool configuration
10#[derive(Debug, Clone)]
11pub struct ThreadPoolConfig {
12    /// Number of worker threads
13    pub num_threads: usize,
14    /// Thread stack size in bytes
15    pub stack_size: Option<usize>,
16    /// Thread name prefix
17    pub thread_name: Option<String>,
18    /// Idle timeout for threads
19    pub idle_timeout: Option<Duration>,
20    /// Maximum chunk size
21    pub max_chunk_size: Option<usize>,
22    /// Minimum chunk size
23    pub min_chunk_size: Option<usize>,
24}
25
26impl Default for ThreadPoolConfig {
27    fn default() -> Self {
28        Self {
29            num_threads: thread::available_parallelism()
30                .map(|n| n.get())
31                .unwrap_or(1),
32            stack_size: None,
33            thread_name: Some("avila-worker".to_string()),
34            idle_timeout: None,
35            max_chunk_size: None,
36            min_chunk_size: Some(1024),
37        }
38    }
39}
40
41impl ThreadPoolConfig {
42    /// Create a new configuration with default values
43    pub fn new() -> Self {
44        Self::default()
45    }
46
47    /// Set the number of threads
48    pub fn num_threads(mut self, n: usize) -> Self {
49        self.num_threads = n;
50        self
51    }
52
53    /// Set the stack size for threads
54    pub fn stack_size(mut self, size: usize) -> Self {
55        self.stack_size = Some(size);
56        self
57    }
58
59    /// Set the thread name prefix
60    pub fn thread_name(mut self, name: impl Into<String>) -> Self {
61        self.thread_name = Some(name.into());
62        self
63    }
64
65    /// Set the idle timeout
66    pub fn idle_timeout(mut self, timeout: Duration) -> Self {
67        self.idle_timeout = Some(timeout);
68        self
69    }
70
71    /// Set the maximum chunk size
72    pub fn max_chunk_size(mut self, size: usize) -> Self {
73        self.max_chunk_size = Some(size);
74        self
75    }
76
77    /// Set the minimum chunk size
78    pub fn min_chunk_size(mut self, size: usize) -> Self {
79        self.min_chunk_size = Some(size);
80        self
81    }
82
83    /// Get effective min chunk size
84    pub fn effective_min_chunk_size(&self) -> usize {
85        self.min_chunk_size.unwrap_or(1024)
86    }
87}
88
89/// Global thread pool configuration
90static CONFIG: OnceLock<Arc<Mutex<ThreadPoolConfig>>> = OnceLock::new();
91
92fn get_config_lock() -> &'static Arc<Mutex<ThreadPoolConfig>> {
93    CONFIG.get_or_init(|| {
94        Arc::new(Mutex::new(ThreadPoolConfig::default()))
95    })
96}
97
98/// Set the global thread pool configuration
99pub fn set_global_config(config: ThreadPoolConfig) {
100    *get_config_lock().lock().unwrap() = config;
101}
102
103/// Get the global thread pool configuration
104pub fn get_global_config() -> ThreadPoolConfig {
105    get_config_lock().lock().unwrap().clone()
106}
107
108#[cfg(test)]
109mod tests {
110    use super::*;
111
112    #[test]
113    fn test_config_builder() {
114        let config = ThreadPoolConfig::new()
115            .num_threads(4)
116            .stack_size(2 * 1024 * 1024)
117            .thread_name("test-worker")
118            .min_chunk_size(2048);
119
120        assert_eq!(config.num_threads, 4);
121        assert_eq!(config.stack_size, Some(2 * 1024 * 1024));
122        assert_eq!(config.thread_name, Some("test-worker".to_string()));
123        assert_eq!(config.min_chunk_size, Some(2048));
124    }
125
126    #[test]
127    fn test_default_config() {
128        let config = ThreadPoolConfig::default();
129        assert!(config.num_threads > 0);
130        assert_eq!(config.min_chunk_size, Some(1024));
131    }
132}