command_executor/
thread_pool_builder.rs

1use crate::queue_type::QueueType;
2use crate::shutdown_mode::ShutdownMode;
3use crate::thread_pool::ThreadPool;
4
5/// Build a [ThreadPool]
6///
7/// Modify default thread pool parameters and build the thread pool
8pub struct ThreadPoolBuilder {
9    name: String,
10    tasks: usize,
11    queue_type: QueueType,
12    queue_size: usize,
13    join_error_handler: fn(String, String),
14    shutdown_mode: ShutdownMode,
15}
16
17impl ThreadPoolBuilder {
18    /// Create a new builder
19    ///
20    /// Default values:
21    /// * `name` - "unnamed"
22    /// * `tasks` - 1
23    /// * `queue_size` - 16
24    /// * `join_error_handler` - a simple panicking error handler
25    /// * `shutdown_mode` - [ShutdownMode::Immediate]
26    ///
27    ///  # Example
28    /// ```
29    ///
30    /// use command_executor::shutdown_mode::ShutdownMode;
31    /// use command_executor::thread_pool::ThreadPool;
32    /// use command_executor::thread_pool_builder::ThreadPoolBuilder;
33    ///
34    /// fn create_thread_pool() -> Result<ThreadPool, anyhow::Error> {
35    ///     ThreadPoolBuilder::new()
36    ///         .with_name_str("example")
37    ///         .with_tasks(4)
38    ///         .with_queue_size(16)
39    ///         .with_shutdown_mode(ShutdownMode::CompletePending)
40    ///         .build()
41    /// }
42    /// ```
43    pub fn new() -> ThreadPoolBuilder {
44        let join_error_handler = |name: String, message: String| {
45            panic!("Thread {name} ended with and error {message}")
46        };
47
48        ThreadPoolBuilder {
49            name: "unnamed".to_string(),
50            tasks: 1,
51            queue_type: QueueType::CrossbeamBlockingQueue,
52            queue_size: 16,
53            join_error_handler,
54            shutdown_mode: ShutdownMode::Immediate,
55        }
56    }
57
58    /// Set the base name for threads in the thread pool
59    pub fn with_name(&mut self, name: String) -> &mut ThreadPoolBuilder {
60        self.name = name.clone();
61        self
62    }
63
64    /// Set the base name for threads in the thread pool. A convenience method that accepts &str
65    pub fn with_name_str(&mut self, name: &str) -> &mut ThreadPoolBuilder {
66        self.name = name.to_string();
67        self
68    }
69
70    /// Set the number of threads in the thread pool
71    pub fn with_tasks(&mut self, tasks: usize) -> &mut ThreadPoolBuilder {
72        self.tasks = tasks;
73        self
74    }
75
76    /// Specify the [ShutdownMode]
77    pub fn with_shutdown_mode(&mut self, shutdown_mode: ShutdownMode) -> &mut ThreadPoolBuilder {
78        self.shutdown_mode = shutdown_mode;
79        self
80    }
81
82    /// Specify the [QueueType]
83    pub fn with_queue_type(&mut self, queue_type: QueueType) -> &mut ThreadPoolBuilder {
84        self.queue_type = queue_type;
85        self
86    }
87
88    /// Specify the queue size for the thread pool
89    pub fn with_queue_size(&mut self, queue_size: usize) -> &mut ThreadPoolBuilder {
90        self.queue_size = queue_size;
91        self
92    }
93
94    /// Set the error handler that is called for each thread that exited with error during join
95    pub fn with_join_error_handler(&mut self, join_error_handler: fn(String, String)) -> &mut ThreadPoolBuilder {
96        self.join_error_handler = join_error_handler;
97        self
98    }
99
100    /// Build the thread pool
101    pub fn build(&self) -> Result<ThreadPool, anyhow::Error> {
102        ThreadPool::new(
103            self.name.clone(),
104            self.tasks,
105            self.queue_type,
106            self.queue_size,
107            self.join_error_handler,
108            self.shutdown_mode.clone(),
109        )
110    }
111}
112
113impl Default for ThreadPoolBuilder {
114    fn default() -> Self {
115        Self::new()
116    }
117}