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