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) graceful_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            graceful_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 after the server has stopped.
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 fails.
77    ///
78    /// A worker fails when it panics or its service cannot be created. The
79    /// stop is graceful only if [`graceful_shutdown`](Self::graceful_shutdown)
80    /// is enabled. Without this option, a failed worker is restarted.
81    ///
82    /// By default, "stop on panic" is disabled.
83    pub fn stop_on_panic(mut self) -> Self {
84        self.stop_on_panic = true;
85        self
86    }
87
88    #[must_use]
89    /// Disables signal handling.
90    ///
91    /// By default, the server stops on SIGINT, SIGTERM, and SIGQUIT.
92    pub fn disable_signals(mut self) -> Self {
93        self.no_signals = true;
94        self
95    }
96
97    #[must_use]
98    /// Enables graceful shutdown on SIGQUIT, fatal signals, and panics.
99    ///
100    /// When enabled, SIGQUIT, SIGSEGV, SIGABRT, application panics, and
101    /// worker failures with "stop on panic" stop the server gracefully.
102    /// SIGTERM always stops gracefully and SIGINT always stops immediately.
103    ///
104    /// By default, these events stop the server immediately.
105    pub fn graceful_shutdown(mut self) -> Self {
106        self.graceful_shutdown = true;
107        self
108    }
109
110    #[must_use]
111    /// Timeout for graceful worker shutdown.
112    ///
113    /// After receiving a stop signal, workers have this much time to finish
114    /// serving requests. Workers that are still alive after the timeout are
115    /// forcefully dropped.
116    ///
117    /// This bounds the worker as a whole, not an individual connection. Each
118    /// connection is bound separately by `IoConfig::set_shutdown_timeout`, so
119    /// this value should leave room for the connections a worker is still
120    /// draining to shut down themselves.
121    ///
122    /// By default, the timeout is set to 30 seconds.
123    pub fn graceful_shutdown_timeout<T: Into<Millis>>(mut self, timeout: T) -> Self {
124        self.graceful_shutdown_timeout = timeout.into();
125        self
126    }
127
128    #[must_use]
129    /// Enables CPU affinity for worker threads.
130    ///
131    /// By default, affinity is disabled.
132    pub fn enable_affinity(mut self) -> Self {
133        self.affinity = true;
134        self
135    }
136
137    /// Starts processing incoming items and returns a server controller.
138    pub fn run<F: ServerConfiguration>(self, factory: F) -> Server<F::Item> {
139        ServerManager::start(self, factory)
140    }
141}