Skip to main content

ntex_server/
pool.rs

1use ntex_util::time::Millis;
2
3use crate::{Server, ServerConfiguration, manager::ServerManager};
4
5const DEFAULT_SHUTDOWN_TIMEOUT: Millis = Millis::from_secs(30);
6
7#[allow(clippy::struct_excessive_bools)]
8#[derive(Debug, Clone)]
9/// Builder for a pool of server workers.
10pub struct WorkerPool {
11    pub(crate) num: usize,
12    pub(crate) name: String,
13    pub(crate) no_signals: bool,
14    pub(crate) stop_runtime: bool,
15    pub(crate) stop_on_panic: bool,
16    pub(crate) graceful_shutdown: bool,
17    pub(crate) shutdown_timeout: Millis,
18    pub(crate) affinity: bool,
19}
20
21impl Default for WorkerPool {
22    fn default() -> Self {
23        Self::new()
24    }
25}
26
27impl WorkerPool {
28    #[must_use]
29    /// Creates a worker pool with default settings.
30    pub fn new() -> Self {
31        let num = core_affinity::get_core_ids().map_or_else(
32            || std::thread::available_parallelism().map_or(2, std::num::NonZeroUsize::get),
33            |v| v.len(),
34        );
35
36        WorkerPool {
37            num,
38            name: "ntex".to_string(),
39            no_signals: false,
40            stop_runtime: false,
41            stop_on_panic: false,
42            graceful_shutdown: false,
43            shutdown_timeout: DEFAULT_SHUTDOWN_TIMEOUT,
44            affinity: false,
45        }
46    }
47
48    #[must_use]
49    /// Sets the worker thread name prefix.
50    ///
51    /// The configured name is used for worker thread names.
52    pub fn name<T: AsRef<str>>(mut self, name: T) -> Self {
53        self.name = name.as_ref().to_string();
54        self
55    }
56
57    #[must_use]
58    /// Sets the number of worker threads to start.
59    ///
60    /// By default, the server uses the number of available logical CPUs.
61    pub fn workers(mut self, num: usize) -> Self {
62        self.num = num;
63        self
64    }
65
66    #[must_use]
67    /// Stops the current ntex runtime when the server manager is dropped.
68    ///
69    /// By default "stop runtime" is disabled.
70    pub fn stop_runtime(mut self) -> Self {
71        self.stop_runtime = true;
72        self
73    }
74
75    #[must_use]
76    /// Stops the server when one of the workers panics.
77    ///
78    /// By default, "stop on panic" is disabled.
79    pub fn stop_on_panic(mut self) -> Self {
80        self.stop_on_panic = true;
81        self
82    }
83
84    #[must_use]
85    /// Disable signal handling.
86    ///
87    /// By default, signal handling is enabled.
88    pub fn disable_signals(mut self) -> Self {
89        self.no_signals = true;
90        self
91    }
92
93    #[must_use]
94    /// Graceful shutdown.
95    ///
96    /// Gracefully shuts down on SIGSEGV or SIGQUIT and app panics.
97    /// Graceful shutdown is always enabled for SIGTERM.
98    /// By default, it is disabled for SIGSEGV and SIGQUIT and panics.
99    pub fn graceful_shutdown(mut self) -> Self {
100        self.graceful_shutdown = true;
101        self
102    }
103
104    #[must_use]
105    /// Timeout for graceful worker shutdown.
106    ///
107    /// After receiving a stop signal, workers have this much time to finish
108    /// serving requests. Workers that are still alive after the timeout are
109    /// forcefully dropped.
110    ///
111    /// By default, the shutdown timeout is set to 30 seconds.
112    pub fn shutdown_timeout<T: Into<Millis>>(mut self, timeout: T) -> Self {
113        self.shutdown_timeout = timeout.into();
114        self
115    }
116
117    #[must_use]
118    /// Enables CPU affinity for worker threads.
119    ///
120    /// By default, affinity is disabled.
121    pub fn enable_affinity(mut self) -> Self {
122        self.affinity = true;
123        self
124    }
125
126    /// Starts processing incoming items and returns a server controller.
127    pub fn run<F: ServerConfiguration>(self, factory: F) -> Server<F::Item> {
128        ServerManager::start(self, factory)
129    }
130}