itsi-scheduler 0.1.5 → 0.1.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of itsi-scheduler might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/Cargo.lock +12 -12
- data/ext/itsi_error/src/from.rs +26 -29
- data/ext/itsi_error/src/lib.rs +1 -1
- data/ext/itsi_rb_helpers/src/lib.rs +27 -4
- data/ext/itsi_server/Cargo.lock +2956 -0
- data/ext/itsi_server/Cargo.toml +6 -2
- data/ext/itsi_server/src/env.rs +43 -0
- data/ext/itsi_server/src/lib.rs +75 -1
- data/ext/itsi_server/src/request/itsi_request.rs +39 -18
- data/ext/itsi_server/src/response/itsi_response.rs +14 -4
- data/ext/itsi_server/src/server/bind.rs +20 -15
- data/ext/itsi_server/src/server/itsi_server.rs +147 -103
- data/ext/itsi_server/src/server/listener.rs +99 -108
- data/ext/itsi_server/src/server/process_worker.rs +10 -3
- data/ext/itsi_server/src/server/serve_strategy/cluster_mode.rs +15 -9
- data/ext/itsi_server/src/server/serve_strategy/single_mode.rs +144 -115
- data/ext/itsi_server/src/server/signal.rs +4 -0
- data/ext/itsi_server/src/server/thread_worker.rs +55 -24
- data/ext/itsi_server/src/server/tls/locked_dir_cache.rs +55 -17
- data/ext/itsi_server/src/server/tls.rs +104 -28
- data/ext/itsi_tracing/src/lib.rs +18 -1
- data/lib/itsi/scheduler/version.rb +1 -1
- metadata +4 -4
- data/ext/itsi_server/src/server/itsi_ca/itsi_ca.crt +0 -13
- data/ext/itsi_server/src/server/itsi_ca/itsi_ca.key +0 -5
@@ -2,24 +2,26 @@ use super::{
|
|
2
2
|
bind::Bind,
|
3
3
|
listener::Listener,
|
4
4
|
serve_strategy::{cluster_mode::ClusterMode, single_mode::SingleMode},
|
5
|
-
signal::{
|
5
|
+
signal::{
|
6
|
+
clear_signal_handlers, reset_signal_handlers, send_shutdown_event, SIGNAL_HANDLER_CHANNEL,
|
7
|
+
},
|
6
8
|
};
|
7
9
|
use crate::{request::itsi_request::ItsiRequest, server::serve_strategy::ServeStrategy};
|
8
10
|
use derive_more::Debug;
|
9
|
-
use itsi_rb_helpers::call_without_gvl;
|
10
|
-
use itsi_tracing::error;
|
11
|
+
use itsi_rb_helpers::{call_without_gvl, HeapVal, HeapValue};
|
12
|
+
use itsi_tracing::{error, run_silently};
|
11
13
|
use magnus::{
|
12
14
|
block::Proc,
|
13
15
|
error::Result,
|
14
|
-
scan_args::{get_kwargs, scan_args, Args, KwArgs},
|
15
|
-
value::
|
16
|
-
RHash, Ruby, Symbol, Value,
|
16
|
+
scan_args::{get_kwargs, scan_args, Args, KwArgs, ScanArgsKw, ScanArgsOpt, ScanArgsRequired},
|
17
|
+
value::ReprValue,
|
18
|
+
ArgList, RArray, RHash, Ruby, Symbol, Value,
|
17
19
|
};
|
18
|
-
use parking_lot::Mutex;
|
19
|
-
use std::{cmp::max, ops::Deref, sync::Arc};
|
20
|
+
use parking_lot::{Mutex, RwLock};
|
21
|
+
use std::{cmp::max, collections::HashMap, ops::Deref, sync::Arc};
|
20
22
|
use tracing::{info, instrument};
|
21
23
|
|
22
|
-
static DEFAULT_BIND: &str = "localhost:3000";
|
24
|
+
static DEFAULT_BIND: &str = "http://localhost:3000";
|
23
25
|
|
24
26
|
#[magnus::wrap(class = "Itsi::Server", free_immediately, size)]
|
25
27
|
#[derive(Clone)]
|
@@ -34,12 +36,11 @@ impl Deref for Server {
|
|
34
36
|
&self.config
|
35
37
|
}
|
36
38
|
}
|
37
|
-
type AfterFork = Mutex<Arc<Option<Box<dyn Fn() + Send + Sync>>>>;
|
38
39
|
|
39
40
|
#[derive(Debug)]
|
40
41
|
pub struct ServerConfig {
|
41
42
|
#[debug(skip)]
|
42
|
-
pub app:
|
43
|
+
pub app: HeapVal,
|
43
44
|
#[allow(unused)]
|
44
45
|
pub workers: u8,
|
45
46
|
#[allow(unused)]
|
@@ -49,12 +50,14 @@ pub struct ServerConfig {
|
|
49
50
|
pub script_name: String,
|
50
51
|
pub(crate) binds: Mutex<Vec<Bind>>,
|
51
52
|
#[debug(skip)]
|
52
|
-
pub
|
53
|
-
#[debug(skip)]
|
54
|
-
pub after_fork: AfterFork,
|
53
|
+
pub hooks: HashMap<String, HeapValue<Proc>>,
|
55
54
|
pub scheduler_class: Option<String>,
|
56
55
|
pub stream_body: Option<bool>,
|
57
56
|
pub worker_memory_limit: Option<u64>,
|
57
|
+
#[debug(skip)]
|
58
|
+
pub(crate) strategy: RwLock<Option<ServeStrategy>>,
|
59
|
+
pub silence: bool,
|
60
|
+
pub oob_gc_responses_threshold: Option<u64>,
|
58
61
|
}
|
59
62
|
|
60
63
|
#[derive(Debug)]
|
@@ -63,6 +66,30 @@ pub enum RequestJob {
|
|
63
66
|
Shutdown,
|
64
67
|
}
|
65
68
|
|
69
|
+
fn extract_args<Req, Opt, Splat>(
|
70
|
+
scan_args: &Args<(), (), (), (), RHash, ()>,
|
71
|
+
primaries: &[&str],
|
72
|
+
rest: &[&str],
|
73
|
+
) -> Result<KwArgs<Req, Opt, Splat>>
|
74
|
+
where
|
75
|
+
Req: ScanArgsRequired,
|
76
|
+
Opt: ScanArgsOpt,
|
77
|
+
Splat: ScanArgsKw,
|
78
|
+
{
|
79
|
+
let symbols: Vec<Symbol> = primaries
|
80
|
+
.iter()
|
81
|
+
.chain(rest.iter())
|
82
|
+
.map(|&name| Symbol::new(name))
|
83
|
+
.collect();
|
84
|
+
|
85
|
+
let hash = scan_args
|
86
|
+
.keywords
|
87
|
+
.funcall::<_, _, RHash>("slice", symbols.into_arg_list_with(&Ruby::get().unwrap()))
|
88
|
+
.unwrap();
|
89
|
+
|
90
|
+
get_kwargs(hash, primaries, rest)
|
91
|
+
}
|
92
|
+
|
66
93
|
impl Server {
|
67
94
|
#[instrument(
|
68
95
|
name = "Itsi",
|
@@ -73,39 +100,44 @@ impl Server {
|
|
73
100
|
pub fn new(args: &[Value]) -> Result<Self> {
|
74
101
|
let scan_args: Args<(), (), (), (), RHash, ()> = scan_args(args)?;
|
75
102
|
|
76
|
-
type
|
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
|
-
|
103
|
+
type Args1 = KwArgs<
|
104
|
+
(Value,),
|
105
|
+
(
|
106
|
+
// Workers
|
107
|
+
Option<u8>,
|
108
|
+
// Threads
|
109
|
+
Option<u8>,
|
110
|
+
// Shutdown Timeout
|
111
|
+
Option<f64>,
|
112
|
+
// Script Name
|
113
|
+
Option<String>,
|
114
|
+
// Binds
|
115
|
+
Option<Vec<String>>,
|
116
|
+
// Stream Body
|
117
|
+
Option<bool>,
|
118
|
+
),
|
119
|
+
(),
|
120
|
+
>;
|
121
|
+
|
122
|
+
type Args2 = KwArgs<
|
123
|
+
(),
|
124
|
+
(
|
125
|
+
// Hooks
|
126
|
+
Option<RHash>,
|
127
|
+
// Scheduler Class
|
128
|
+
Option<String>,
|
129
|
+
// Worker Memory Limit
|
130
|
+
Option<u64>,
|
131
|
+
// Out-of-band GC Responses Threshold
|
132
|
+
Option<u64>,
|
133
|
+
// Silence
|
134
|
+
Option<bool>,
|
135
|
+
),
|
136
|
+
(),
|
137
|
+
>;
|
138
|
+
|
139
|
+
let args1: Args1 = extract_args(
|
140
|
+
&scan_args,
|
109
141
|
&["app"],
|
110
142
|
&[
|
111
143
|
"workers",
|
@@ -113,24 +145,43 @@ impl Server {
|
|
113
145
|
"shutdown_timeout",
|
114
146
|
"script_name",
|
115
147
|
"binds",
|
116
|
-
"before_fork",
|
117
|
-
"after_fork",
|
118
|
-
"scheduler_class",
|
119
148
|
"stream_body",
|
120
149
|
],
|
121
150
|
)?;
|
122
151
|
|
123
|
-
let args2:
|
124
|
-
scan_args
|
125
|
-
.keywords
|
126
|
-
.funcall::<_, _, RHash>("slice", (Symbol::new("worker_memory_limit"),))
|
127
|
-
.unwrap(),
|
152
|
+
let args2: Args2 = extract_args(
|
153
|
+
&scan_args,
|
128
154
|
&[],
|
129
|
-
&[
|
155
|
+
&[
|
156
|
+
"hooks",
|
157
|
+
"scheduler_class",
|
158
|
+
"worker_memory_limit",
|
159
|
+
"oob_gc_responses_threshold",
|
160
|
+
"silence",
|
161
|
+
],
|
130
162
|
)?;
|
131
163
|
|
164
|
+
let hooks = args2
|
165
|
+
.optional
|
166
|
+
.0
|
167
|
+
.map(|rhash| -> Result<HashMap<String, HeapValue<Proc>>> {
|
168
|
+
let mut hook_map: HashMap<String, HeapValue<Proc>> = HashMap::new();
|
169
|
+
for pair in rhash.enumeratorize::<_, ()>("each", ()) {
|
170
|
+
if let Some(pair_value) = RArray::from_value(pair?) {
|
171
|
+
if let (Ok(key), Ok(value)) =
|
172
|
+
(pair_value.entry::<Value>(0), pair_value.entry::<Proc>(1))
|
173
|
+
{
|
174
|
+
hook_map.insert(key.to_string(), HeapValue::from(value));
|
175
|
+
}
|
176
|
+
}
|
177
|
+
}
|
178
|
+
Ok(hook_map)
|
179
|
+
})
|
180
|
+
.transpose()?
|
181
|
+
.unwrap_or_default();
|
182
|
+
|
132
183
|
let config = ServerConfig {
|
133
|
-
app:
|
184
|
+
app: HeapVal::from(args1.required.0),
|
134
185
|
workers: max(args1.optional.0.unwrap_or(1), 1),
|
135
186
|
threads: max(args1.optional.1.unwrap_or(1), 1),
|
136
187
|
shutdown_timeout: args1.optional.2.unwrap_or(5.0),
|
@@ -144,33 +195,21 @@ impl Server {
|
|
144
195
|
.map(|s| s.parse())
|
145
196
|
.collect::<itsi_error::Result<Vec<Bind>>>()?,
|
146
197
|
),
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
}) as Box<dyn FnOnce() + Send + Sync>
|
155
|
-
})),
|
156
|
-
after_fork: Mutex::new(Arc::new(args1.optional.6.map(|p| {
|
157
|
-
let opaque_proc = Opaque::from(p);
|
158
|
-
Box::new(move || {
|
159
|
-
opaque_proc
|
160
|
-
.get_inner_with(&Ruby::get().unwrap())
|
161
|
-
.call::<_, Value>(())
|
162
|
-
.unwrap();
|
163
|
-
}) as Box<dyn Fn() + Send + Sync>
|
164
|
-
}))),
|
165
|
-
scheduler_class: args1.optional.7.clone(),
|
166
|
-
stream_body: args1.optional.8,
|
167
|
-
worker_memory_limit: args2.optional.0,
|
198
|
+
stream_body: args1.optional.5,
|
199
|
+
hooks,
|
200
|
+
scheduler_class: args2.optional.1.clone(),
|
201
|
+
worker_memory_limit: args2.optional.2,
|
202
|
+
strategy: RwLock::new(None),
|
203
|
+
oob_gc_responses_threshold: args2.optional.3,
|
204
|
+
silence: args2.optional.4.is_some_and(|s| s),
|
168
205
|
};
|
169
206
|
|
170
|
-
if
|
171
|
-
|
172
|
-
|
173
|
-
|
207
|
+
if !config.silence {
|
208
|
+
if let Some(scheduler_class) = args2.optional.1 {
|
209
|
+
info!(scheduler_class, fiber_scheduler = true);
|
210
|
+
} else {
|
211
|
+
info!(fiber_scheduler = false);
|
212
|
+
}
|
174
213
|
}
|
175
214
|
|
176
215
|
Ok(Server {
|
@@ -179,7 +218,7 @@ impl Server {
|
|
179
218
|
}
|
180
219
|
|
181
220
|
#[instrument(name = "Bind", skip_all, fields(binds=format!("{:?}", self.config.binds.lock())))]
|
182
|
-
pub(crate) fn
|
221
|
+
pub(crate) fn build_listeners(&self) -> Result<Vec<Listener>> {
|
183
222
|
let listeners = self
|
184
223
|
.config
|
185
224
|
.binds
|
@@ -189,17 +228,15 @@ impl Server {
|
|
189
228
|
.map(Listener::try_from)
|
190
229
|
.collect::<std::result::Result<Vec<Listener>, _>>()?
|
191
230
|
.into_iter()
|
192
|
-
.map(Arc::new)
|
193
231
|
.collect::<Vec<_>>();
|
194
232
|
info!("Bound {:?} listeners", listeners.len());
|
195
|
-
Ok(
|
233
|
+
Ok(listeners)
|
196
234
|
}
|
197
235
|
|
198
|
-
pub(crate) fn build_strategy(
|
199
|
-
self
|
200
|
-
listeners: Arc<Vec<Arc<Listener>>>,
|
201
|
-
) -> Result<ServeStrategy> {
|
236
|
+
pub(crate) fn build_strategy(self) -> Result<()> {
|
237
|
+
let listeners = self.build_listeners()?;
|
202
238
|
let server = Arc::new(self);
|
239
|
+
let server_clone = server.clone();
|
203
240
|
|
204
241
|
let strategy = if server.config.workers == 1 {
|
205
242
|
ServeStrategy::Single(Arc::new(SingleMode::new(
|
@@ -214,31 +251,38 @@ impl Server {
|
|
214
251
|
SIGNAL_HANDLER_CHANNEL.0.clone(),
|
215
252
|
)))
|
216
253
|
};
|
217
|
-
|
254
|
+
|
255
|
+
*server_clone.strategy.write() = Some(strategy);
|
256
|
+
Ok(())
|
257
|
+
}
|
258
|
+
|
259
|
+
pub fn stop(&self) -> Result<()> {
|
260
|
+
send_shutdown_event();
|
261
|
+
Ok(())
|
218
262
|
}
|
219
263
|
|
220
264
|
pub fn start(&self) -> Result<()> {
|
265
|
+
if self.silence {
|
266
|
+
run_silently(|| self.build_and_run_strategy())
|
267
|
+
} else {
|
268
|
+
self.build_and_run_strategy()
|
269
|
+
}
|
270
|
+
}
|
271
|
+
|
272
|
+
fn build_and_run_strategy(&self) -> Result<()> {
|
221
273
|
reset_signal_handlers();
|
222
274
|
let rself = self.clone();
|
223
|
-
let listeners = self.listeners()?;
|
224
|
-
let listeners_clone = listeners.clone();
|
225
275
|
call_without_gvl(move || -> Result<()> {
|
226
|
-
|
227
|
-
if let Err(e) = strategy.run() {
|
276
|
+
rself.clone().build_strategy()?;
|
277
|
+
if let Err(e) = rself.strategy.read().as_ref().unwrap().run() {
|
228
278
|
error!("Error running server: {}", e);
|
229
|
-
strategy.stop()?;
|
279
|
+
rself.strategy.read().as_ref().unwrap().stop()?;
|
230
280
|
}
|
231
|
-
drop(strategy);
|
232
281
|
Ok(())
|
233
282
|
})?;
|
234
|
-
if let Ok(listeners) = Arc::try_unwrap(listeners) {
|
235
|
-
listeners.into_iter().for_each(|listener| {
|
236
|
-
if let Ok(listener) = Arc::try_unwrap(listener) {
|
237
|
-
listener.unbind()
|
238
|
-
};
|
239
|
-
});
|
240
|
-
}
|
241
283
|
clear_signal_handlers();
|
284
|
+
self.strategy.write().take();
|
285
|
+
info!("Server stopped");
|
242
286
|
Ok(())
|
243
287
|
}
|
244
288
|
}
|
@@ -1,6 +1,7 @@
|
|
1
1
|
use super::bind::{Bind, BindAddress};
|
2
2
|
use super::bind_protocol::BindProtocol;
|
3
3
|
use super::io_stream::IoStream;
|
4
|
+
use super::serve_strategy::single_mode::RunningPhase;
|
4
5
|
use super::tls::ItsiTlsAcceptor;
|
5
6
|
use itsi_error::{ItsiError, Result};
|
6
7
|
use itsi_tracing::info;
|
@@ -11,6 +12,7 @@ use std::{os::unix::net::UnixListener, path::PathBuf};
|
|
11
12
|
use tokio::net::TcpListener as TokioTcpListener;
|
12
13
|
use tokio::net::UnixListener as TokioUnixListener;
|
13
14
|
use tokio::net::{unix, TcpStream, UnixStream};
|
15
|
+
use tokio::sync::watch::Receiver;
|
14
16
|
use tokio_rustls::TlsAcceptor;
|
15
17
|
use tokio_stream::StreamExt;
|
16
18
|
use tracing::error;
|
@@ -23,45 +25,79 @@ pub(crate) enum Listener {
|
|
23
25
|
}
|
24
26
|
|
25
27
|
pub(crate) enum TokioListener {
|
26
|
-
Tcp
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
Unix {
|
38
|
-
listener: TokioUnixListener,
|
39
|
-
},
|
40
|
-
UnixTls {
|
41
|
-
listener: TokioUnixListener,
|
42
|
-
acceptor: ItsiTlsAcceptor,
|
43
|
-
},
|
28
|
+
Tcp(TokioTcpListener),
|
29
|
+
TcpTls(TokioTcpListener, ItsiTlsAcceptor),
|
30
|
+
Unix(TokioUnixListener),
|
31
|
+
UnixTls(TokioUnixListener, ItsiTlsAcceptor),
|
32
|
+
}
|
33
|
+
|
34
|
+
#[derive(Debug, Clone)]
|
35
|
+
pub struct ListenerInfo {
|
36
|
+
pub host: String,
|
37
|
+
pub port: u16,
|
38
|
+
pub scheme: String,
|
44
39
|
}
|
45
40
|
|
46
41
|
impl TokioListener {
|
47
|
-
pub fn
|
42
|
+
pub fn listener_info(&self) -> ListenerInfo {
|
48
43
|
match self {
|
49
|
-
TokioListener::Tcp
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
44
|
+
TokioListener::Tcp(listener) => ListenerInfo {
|
45
|
+
host: listener
|
46
|
+
.local_addr()
|
47
|
+
.unwrap()
|
48
|
+
.ip()
|
49
|
+
.to_canonical()
|
50
|
+
.to_string(),
|
51
|
+
port: listener.local_addr().unwrap().port(),
|
52
|
+
scheme: "http".to_string(),
|
53
|
+
},
|
54
|
+
TokioListener::TcpTls(listener, _) => ListenerInfo {
|
55
|
+
host: listener
|
56
|
+
.local_addr()
|
57
|
+
.unwrap()
|
58
|
+
.ip()
|
59
|
+
.to_canonical()
|
60
|
+
.to_string(),
|
61
|
+
port: listener.local_addr().unwrap().port(),
|
62
|
+
scheme: "https".to_string(),
|
63
|
+
},
|
64
|
+
TokioListener::Unix(listener) => ListenerInfo {
|
65
|
+
host: listener
|
66
|
+
.local_addr()
|
67
|
+
.unwrap()
|
68
|
+
.as_pathname()
|
69
|
+
.unwrap()
|
70
|
+
.to_str()
|
71
|
+
.unwrap()
|
72
|
+
.to_owned(),
|
73
|
+
port: 0,
|
74
|
+
scheme: "unix".to_string(),
|
75
|
+
},
|
76
|
+
TokioListener::UnixTls(listener, _) => ListenerInfo {
|
77
|
+
host: listener
|
78
|
+
.local_addr()
|
79
|
+
.unwrap()
|
80
|
+
.as_pathname()
|
81
|
+
.unwrap()
|
82
|
+
.to_str()
|
83
|
+
.unwrap()
|
84
|
+
.to_owned(),
|
85
|
+
port: 0,
|
86
|
+
scheme: "ssl".to_string(),
|
87
|
+
},
|
88
|
+
}
|
54
89
|
}
|
90
|
+
|
55
91
|
pub(crate) async fn accept(&self) -> Result<IoStream> {
|
56
92
|
match self {
|
57
|
-
TokioListener::Tcp
|
58
|
-
TokioListener::TcpTls {
|
59
|
-
listener, acceptor
|
60
|
-
}
|
61
|
-
TokioListener::Unix
|
62
|
-
TokioListener::UnixTls {
|
63
|
-
listener, acceptor
|
64
|
-
}
|
93
|
+
TokioListener::Tcp(listener) => TokioListener::accept_tcp(listener).await,
|
94
|
+
TokioListener::TcpTls(listener, acceptor) => {
|
95
|
+
TokioListener::accept_tls(listener, acceptor).await
|
96
|
+
}
|
97
|
+
TokioListener::Unix(listener) => TokioListener::accept_unix(listener).await,
|
98
|
+
TokioListener::UnixTls(listener, acceptor) => {
|
99
|
+
TokioListener::accept_unix_tls(listener, acceptor).await
|
100
|
+
}
|
65
101
|
}
|
66
102
|
}
|
67
103
|
|
@@ -70,17 +106,24 @@ impl TokioListener {
|
|
70
106
|
Self::to_tokio_io(Stream::TcpStream(tcp_stream), None).await
|
71
107
|
}
|
72
108
|
|
73
|
-
pub async fn spawn_state_task(&self) {
|
74
|
-
if let TokioListener::TcpTls
|
75
|
-
|
76
|
-
|
77
|
-
|
109
|
+
pub async fn spawn_state_task(&self, mut shutdown_receiver: Receiver<RunningPhase>) {
|
110
|
+
if let TokioListener::TcpTls(
|
111
|
+
_,
|
112
|
+
ItsiTlsAcceptor::Automatic(_acme_acceptor, state, _server_config),
|
113
|
+
) = self
|
78
114
|
{
|
79
115
|
let mut state = state.lock().await;
|
80
116
|
loop {
|
81
|
-
|
82
|
-
|
83
|
-
|
117
|
+
tokio::select! {
|
118
|
+
stream_event = StreamExt::next(&mut *state) => {
|
119
|
+
match stream_event {
|
120
|
+
Some(event) => info!("ACME Event: {:?}", event),
|
121
|
+
None => error!("Received no acme event"),
|
122
|
+
}
|
123
|
+
},
|
124
|
+
_ = shutdown_receiver.changed() => {
|
125
|
+
break;
|
126
|
+
}
|
84
127
|
}
|
85
128
|
}
|
86
129
|
}
|
@@ -175,33 +218,6 @@ impl TokioListener {
|
|
175
218
|
},
|
176
219
|
}
|
177
220
|
}
|
178
|
-
|
179
|
-
pub(crate) fn scheme(&self) -> String {
|
180
|
-
match self {
|
181
|
-
TokioListener::Tcp { .. } => "http".to_string(),
|
182
|
-
TokioListener::TcpTls { .. } => "https".to_string(),
|
183
|
-
TokioListener::Unix { .. } => "http".to_string(),
|
184
|
-
TokioListener::UnixTls { .. } => "https".to_string(),
|
185
|
-
}
|
186
|
-
}
|
187
|
-
|
188
|
-
pub(crate) fn port(&self) -> u16 {
|
189
|
-
match self {
|
190
|
-
TokioListener::Tcp { port, .. } => *port,
|
191
|
-
TokioListener::TcpTls { port, .. } => *port,
|
192
|
-
TokioListener::Unix { .. } => 0,
|
193
|
-
TokioListener::UnixTls { .. } => 0,
|
194
|
-
}
|
195
|
-
}
|
196
|
-
|
197
|
-
pub(crate) fn host(&self) -> String {
|
198
|
-
match self {
|
199
|
-
TokioListener::Tcp { host, .. } => host.to_string(),
|
200
|
-
TokioListener::TcpTls { host, .. } => host.to_string(),
|
201
|
-
TokioListener::Unix { .. } => "unix".to_string(),
|
202
|
-
TokioListener::UnixTls { .. } => "unix".to_string(),
|
203
|
-
}
|
204
|
-
}
|
205
221
|
}
|
206
222
|
|
207
223
|
enum Stream {
|
@@ -227,48 +243,22 @@ impl std::fmt::Display for SockAddr {
|
|
227
243
|
}
|
228
244
|
|
229
245
|
impl Listener {
|
230
|
-
pub fn
|
246
|
+
pub fn into_tokio_listener(self) -> TokioListener {
|
231
247
|
match self {
|
232
|
-
Listener::Tcp(listener) =>
|
233
|
-
|
234
|
-
|
235
|
-
Listener::
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
.ip()
|
247
|
-
.to_canonical()
|
248
|
-
.to_string(),
|
249
|
-
port: listener.local_addr().unwrap().port(),
|
250
|
-
},
|
251
|
-
Listener::TcpTls((listener, acceptor)) => TokioListener::TcpTls {
|
252
|
-
listener: TokioTcpListener::from_std(TcpListener::try_clone(listener).unwrap())
|
253
|
-
.unwrap(),
|
254
|
-
acceptor: acceptor.clone(),
|
255
|
-
host: listener
|
256
|
-
.local_addr()
|
257
|
-
.unwrap()
|
258
|
-
.ip()
|
259
|
-
.to_canonical()
|
260
|
-
.to_string(),
|
261
|
-
port: listener.local_addr().unwrap().port(),
|
262
|
-
},
|
263
|
-
Listener::Unix(listener) => TokioListener::Unix {
|
264
|
-
listener: TokioUnixListener::from_std(UnixListener::try_clone(listener).unwrap())
|
265
|
-
.unwrap(),
|
266
|
-
},
|
267
|
-
Listener::UnixTls((listener, acceptor)) => TokioListener::UnixTls {
|
268
|
-
listener: TokioUnixListener::from_std(UnixListener::try_clone(listener).unwrap())
|
269
|
-
.unwrap(),
|
270
|
-
acceptor: acceptor.clone(),
|
271
|
-
},
|
248
|
+
Listener::Tcp(listener) => {
|
249
|
+
TokioListener::Tcp(TokioTcpListener::from_std(listener).unwrap())
|
250
|
+
}
|
251
|
+
Listener::TcpTls((listener, acceptor)) => TokioListener::TcpTls(
|
252
|
+
TokioTcpListener::from_std(listener).unwrap(),
|
253
|
+
acceptor.clone(),
|
254
|
+
),
|
255
|
+
Listener::Unix(listener) => {
|
256
|
+
TokioListener::Unix(TokioUnixListener::from_std(listener).unwrap())
|
257
|
+
}
|
258
|
+
Listener::UnixTls((listener, acceptor)) => TokioListener::UnixTls(
|
259
|
+
TokioUnixListener::from_std(listener).unwrap(),
|
260
|
+
acceptor.clone(),
|
261
|
+
),
|
272
262
|
}
|
273
263
|
}
|
274
264
|
}
|
@@ -307,6 +297,7 @@ fn connect_tcp_socket(addr: IpAddr, port: u16) -> Result<TcpListener> {
|
|
307
297
|
socket.set_nonblocking(true).ok();
|
308
298
|
socket.set_nodelay(true).ok();
|
309
299
|
socket.set_recv_buffer_size(262_144).ok();
|
300
|
+
info!("Binding to {:?}", socket_address);
|
310
301
|
socket.bind(&socket_address.into())?;
|
311
302
|
socket.listen(1024)?;
|
312
303
|
Ok(socket.into())
|
@@ -53,8 +53,8 @@ impl ProcessWorker {
|
|
53
53
|
}
|
54
54
|
*self.child_pid.lock() = None;
|
55
55
|
}
|
56
|
-
|
57
|
-
|
56
|
+
match call_with_gvl(|_ruby| fork(cluster_template.server.hooks.get("after_fork").cloned()))
|
57
|
+
{
|
58
58
|
Some(pid) => {
|
59
59
|
*self.child_pid.lock() = Some(Pid::from_raw(pid));
|
60
60
|
}
|
@@ -67,7 +67,7 @@ impl ProcessWorker {
|
|
67
67
|
}
|
68
68
|
match SingleMode::new(
|
69
69
|
cluster_template.server.clone(),
|
70
|
-
cluster_template.listeners.
|
70
|
+
cluster_template.listeners.lock().drain(..).collect(),
|
71
71
|
cluster_template.lifecycle_channel.clone(),
|
72
72
|
) {
|
73
73
|
Ok(single_mode) => {
|
@@ -83,6 +83,13 @@ impl ProcessWorker {
|
|
83
83
|
Ok(())
|
84
84
|
}
|
85
85
|
|
86
|
+
pub fn pid(&self) -> i32 {
|
87
|
+
if let Some(pid) = *self.child_pid.lock() {
|
88
|
+
return pid.as_raw();
|
89
|
+
}
|
90
|
+
0
|
91
|
+
}
|
92
|
+
|
86
93
|
pub(crate) fn memory_usage(&self) -> Option<u64> {
|
87
94
|
if let Some(pid) = *self.child_pid.lock() {
|
88
95
|
let s = System::new_all();
|