moirai_core/executor/builder.rs
1//! Executor builder implementation.
2
3use super::{
4 config::{CleanupConfig, ExecutorConfig, MemoryConfig, PreemptionConfig},
5 placement::WorkerPlacement,
6};
7use crate::platform::String;
8
9/// Builder for creating executors with custom configuration.
10pub struct ExecutorBuilder {
11 pub(crate) config: ExecutorConfig,
12}
13
14impl ExecutorBuilder {
15 /// Creates a new executor builder with default settings.
16 ///
17 /// # Returns
18 /// A new builder instance ready for configuration
19 #[must_use]
20 pub fn new() -> Self {
21 Self {
22 config: ExecutorConfig::default(),
23 }
24 }
25
26 /// Sets the number of worker threads for CPU-bound tasks.
27 ///
28 /// # Arguments
29 /// * `count` - Number of worker threads to create
30 ///
31 /// # Returns
32 /// The builder instance for method chaining
33 #[must_use]
34 pub fn worker_threads(mut self, count: usize) -> Self {
35 self.config.worker_threads = count;
36 self
37 }
38
39 /// Sets whether each worker is confined to one logical processor.
40 ///
41 /// # Arguments
42 /// * `placement` - The worker placement policy
43 ///
44 /// # Returns
45 /// The builder instance for method chaining
46 #[must_use]
47 pub fn worker_placement(mut self, placement: WorkerPlacement) -> Self {
48 self.config.worker_placement = placement;
49 self
50 }
51
52 /// Sets the number of threads for async task execution.
53 ///
54 /// # Arguments
55 /// * `count` - Number of async threads to create
56 ///
57 /// # Returns
58 /// The builder instance for method chaining
59 #[must_use]
60 pub fn async_threads(mut self, count: usize) -> Self {
61 self.config.async_threads = count;
62 self
63 }
64
65 /// Sets the aggregate maximum of the workers' external admission queues.
66 ///
67 /// # Arguments
68 /// * `size` - Maximum queued tasks across all worker injectors
69 ///
70 /// # Returns
71 /// The builder instance for method chaining
72 #[must_use]
73 pub fn max_global_queue_size(mut self, size: usize) -> Self {
74 self.config.max_global_queue_size = size;
75 self
76 }
77
78 /// Sets the initial capacity of each resizable local priority queue.
79 ///
80 /// # Arguments
81 /// * `size` - Requested initial slots per local priority queue
82 ///
83 /// # Returns
84 /// The builder instance for method chaining
85 #[must_use]
86 pub fn local_queue_initial_capacity(mut self, size: usize) -> Self {
87 self.config.local_queue_initial_capacity = size;
88 self
89 }
90
91 /// Sets the thread name prefix for executor threads.
92 ///
93 /// # Arguments
94 /// * `prefix` - String prefix for thread names
95 ///
96 /// # Returns
97 /// The builder instance for method chaining
98 #[must_use]
99 pub fn thread_name_prefix(mut self, prefix: impl Into<String>) -> Self {
100 self.config.thread_name_prefix = prefix.into();
101 self
102 }
103
104 /// Enable or disable metrics collection.
105 #[cfg(feature = "metrics")]
106 #[must_use]
107 pub fn enable_metrics(mut self, enabled: bool) -> Self {
108 self.config.enable_metrics = enabled;
109 self
110 }
111
112 /// Configures preemption behavior for the executor.
113 ///
114 /// # Arguments
115 /// * `config` - Preemption configuration settings
116 ///
117 /// # Returns
118 /// The builder instance for method chaining
119 #[must_use]
120 pub fn preemption_config(mut self, config: PreemptionConfig) -> Self {
121 self.config.preemption = config;
122 self
123 }
124
125 /// Configures memory management settings.
126 ///
127 /// # Arguments
128 /// * `config` - Memory configuration settings
129 ///
130 /// # Returns
131 /// The builder instance for method chaining
132 #[must_use]
133 pub fn memory_config(mut self, config: MemoryConfig) -> Self {
134 self.config.memory = config;
135 self
136 }
137
138 /// Configures cleanup and maintenance settings.
139 ///
140 /// # Arguments
141 /// * `config` - Cleanup configuration settings
142 ///
143 /// # Returns
144 /// The builder instance for method chaining
145 #[must_use]
146 pub fn cleanup_config(mut self, config: CleanupConfig) -> Self {
147 self.config.cleanup = config;
148 self
149 }
150}
151
152impl Default for ExecutorBuilder {
153 fn default() -> Self {
154 Self::new()
155 }
156}
157
158#[cfg(test)]
159mod tests {
160 use super::{ExecutorBuilder, WorkerPlacement};
161
162 #[test]
163 fn local_queue_initial_capacity_updates_the_configuration() {
164 let builder = ExecutorBuilder::new().local_queue_initial_capacity(17);
165
166 assert_eq!(builder.config.local_queue_initial_capacity, 17);
167 }
168
169 #[test]
170 fn worker_placement_defaults_to_unbound_and_is_settable() {
171 assert_eq!(
172 ExecutorBuilder::new().config.worker_placement,
173 WorkerPlacement::Unbound
174 );
175 assert_eq!(
176 ExecutorBuilder::new()
177 .worker_placement(WorkerPlacement::Pinned)
178 .config
179 .worker_placement,
180 WorkerPlacement::Pinned
181 );
182 }
183}