1use std::sync::{Arc, Mutex, OnceLock};
6use std::thread;
7use std::time::Duration;
8
9#[derive(Debug, Clone)]
11pub struct ThreadPoolConfig {
12 pub num_threads: usize,
14 pub stack_size: Option<usize>,
16 pub thread_name: Option<String>,
18 pub idle_timeout: Option<Duration>,
20 pub max_chunk_size: Option<usize>,
22 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 pub fn new() -> Self {
44 Self::default()
45 }
46
47 pub fn num_threads(mut self, n: usize) -> Self {
49 self.num_threads = n;
50 self
51 }
52
53 pub fn stack_size(mut self, size: usize) -> Self {
55 self.stack_size = Some(size);
56 self
57 }
58
59 pub fn thread_name(mut self, name: impl Into<String>) -> Self {
61 self.thread_name = Some(name.into());
62 self
63 }
64
65 pub fn idle_timeout(mut self, timeout: Duration) -> Self {
67 self.idle_timeout = Some(timeout);
68 self
69 }
70
71 pub fn max_chunk_size(mut self, size: usize) -> Self {
73 self.max_chunk_size = Some(size);
74 self
75 }
76
77 pub fn min_chunk_size(mut self, size: usize) -> Self {
79 self.min_chunk_size = Some(size);
80 self
81 }
82
83 pub fn effective_min_chunk_size(&self) -> usize {
85 self.min_chunk_size.unwrap_or(1024)
86 }
87}
88
89static 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
98pub fn set_global_config(config: ThreadPoolConfig) {
100 *get_config_lock().lock().unwrap() = config;
101}
102
103pub 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}