itsi-server 0.1.1 → 0.1.3
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.
- checksums.yaml +4 -4
- data/exe/itsi +88 -28
- data/ext/itsi_error/Cargo.toml +2 -0
- data/ext/itsi_error/src/from.rs +70 -0
- data/ext/itsi_error/src/lib.rs +10 -37
- data/ext/itsi_instrument_entry/Cargo.toml +15 -0
- data/ext/itsi_instrument_entry/src/lib.rs +31 -0
- data/ext/itsi_rb_helpers/Cargo.toml +2 -0
- data/ext/itsi_rb_helpers/src/heap_value.rs +121 -0
- data/ext/itsi_rb_helpers/src/lib.rs +90 -10
- data/ext/itsi_scheduler/Cargo.toml +24 -0
- data/ext/itsi_scheduler/extconf.rb +6 -0
- data/ext/itsi_scheduler/src/itsi_scheduler/io_helpers.rs +56 -0
- data/ext/itsi_scheduler/src/itsi_scheduler/io_waiter.rs +44 -0
- data/ext/itsi_scheduler/src/itsi_scheduler/timer.rs +44 -0
- data/ext/itsi_scheduler/src/itsi_scheduler.rs +308 -0
- data/ext/itsi_scheduler/src/lib.rs +38 -0
- data/ext/itsi_server/Cargo.toml +14 -2
- data/ext/itsi_server/extconf.rb +1 -1
- data/ext/itsi_server/src/body_proxy/big_bytes.rs +104 -0
- data/ext/itsi_server/src/body_proxy/itsi_body_proxy.rs +122 -0
- data/ext/itsi_server/src/body_proxy/mod.rs +2 -0
- data/ext/itsi_server/src/lib.rs +58 -7
- data/ext/itsi_server/src/request/itsi_request.rs +238 -104
- data/ext/itsi_server/src/response/itsi_response.rs +347 -0
- data/ext/itsi_server/src/response/mod.rs +1 -0
- data/ext/itsi_server/src/server/bind.rs +50 -20
- data/ext/itsi_server/src/server/bind_protocol.rs +37 -0
- data/ext/itsi_server/src/server/io_stream.rs +104 -0
- data/ext/itsi_server/src/server/itsi_ca/itsi_ca.crt +11 -30
- data/ext/itsi_server/src/server/itsi_ca/itsi_ca.key +3 -50
- data/ext/itsi_server/src/server/itsi_server.rs +196 -134
- data/ext/itsi_server/src/server/lifecycle_event.rs +9 -0
- data/ext/itsi_server/src/server/listener.rs +184 -127
- data/ext/itsi_server/src/server/mod.rs +7 -1
- data/ext/itsi_server/src/server/process_worker.rs +196 -0
- data/ext/itsi_server/src/server/serve_strategy/cluster_mode.rs +254 -0
- data/ext/itsi_server/src/server/serve_strategy/mod.rs +27 -0
- data/ext/itsi_server/src/server/serve_strategy/single_mode.rs +241 -0
- data/ext/itsi_server/src/server/signal.rs +70 -0
- data/ext/itsi_server/src/server/thread_worker.rs +368 -0
- data/ext/itsi_server/src/server/tls.rs +42 -28
- data/ext/itsi_tracing/Cargo.toml +4 -0
- data/ext/itsi_tracing/src/lib.rs +36 -6
- data/lib/itsi/request.rb +30 -14
- data/lib/itsi/server/rack/handler/itsi.rb +25 -0
- data/lib/itsi/server/scheduler_mode.rb +6 -0
- data/lib/itsi/server/version.rb +1 -1
- data/lib/itsi/server.rb +82 -2
- data/lib/itsi/signals.rb +23 -0
- data/lib/itsi/stream_io.rb +38 -0
- metadata +38 -25
- data/ext/itsi_server/src/server/transfer_protocol.rs +0 -23
- data/ext/itsi_server/src/stream_writer/mod.rs +0 -21
@@ -1,52 +1,5 @@
|
|
1
1
|
-----BEGIN PRIVATE KEY-----
|
2
|
-
|
3
|
-
|
4
|
-
+
|
5
|
-
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
-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
-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
-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
-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
-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
-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
-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
-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
-
LnlHeLHZFPKg6/0BV3YXIiRe+S6mOMEcuMPaT5PSAkrbPq42t9OCNkXLIMTfGxCV
|
15
|
-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
-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
-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
-
lN1fu3rEunwxu6Wwo58NhaF76z/RX64ENLXQpPox5N76MDRhfI5OVyiPRK2IpAfO
|
19
|
-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
-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
-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
-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
-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
-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
-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
-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
-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
-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
-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
-
eRk/b2CFkpV1NNT9A5RaoI+aL4qfgOdDCBA/6lQy3P3aurIn0qAjNEsFl45mOBEy
|
31
|
-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
-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
-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
-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
-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
-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
-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
-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
-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
-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
-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
-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
-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
-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
-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
-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
-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
-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
-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
-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
|
51
|
-
cN5973/E4MpAKMt1shs0YWr3axraOhkg
|
2
|
+
MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgC7WOxDmO7pBvDvYn
|
3
|
+
YI8+z2/2c0ChxBsuJkQq/dXi1RyhRANCAASoZ0L1WLWvsBG+pKQ9eQCCJXmCfYwx
|
4
|
+
N4Rp9qCtZPsbWidKH8b5Cy3GXrWR8U0s5OLLo1KAC0ob6B+94JOjQ9zP
|
52
5
|
-----END PRIVATE KEY-----
|
@@ -1,56 +1,111 @@
|
|
1
1
|
use super::{
|
2
2
|
bind::Bind,
|
3
|
-
listener::
|
3
|
+
listener::Listener,
|
4
|
+
serve_strategy::{cluster_mode::ClusterMode, single_mode::SingleMode},
|
5
|
+
signal::{clear_signal_handlers, reset_signal_handlers, SIGNAL_HANDLER_CHANNEL},
|
4
6
|
};
|
5
|
-
use crate::{request::itsi_request::ItsiRequest,
|
6
|
-
use bytes::Bytes;
|
7
|
+
use crate::{request::itsi_request::ItsiRequest, server::serve_strategy::ServeStrategy};
|
7
8
|
use derive_more::Debug;
|
8
|
-
use
|
9
|
-
use
|
10
|
-
body::Incoming, header::HeaderName, service::service_fn, HeaderMap, Request, Response,
|
11
|
-
StatusCode,
|
12
|
-
};
|
13
|
-
use hyper_util::{rt::TokioExecutor, server::conn::auto::Builder};
|
14
|
-
use itsi_tracing::{error, info};
|
9
|
+
use itsi_rb_helpers::call_without_gvl;
|
10
|
+
use itsi_tracing::error;
|
15
11
|
use magnus::{
|
12
|
+
block::Proc,
|
16
13
|
error::Result,
|
17
14
|
scan_args::{get_kwargs, scan_args, Args, KwArgs},
|
18
|
-
value::{Opaque, ReprValue},
|
19
|
-
RHash, Ruby, Value,
|
15
|
+
value::{InnerValue, Opaque, ReprValue},
|
16
|
+
RHash, Ruby, Symbol, Value,
|
20
17
|
};
|
21
18
|
use parking_lot::Mutex;
|
22
|
-
use std::{
|
23
|
-
use
|
24
|
-
|
19
|
+
use std::{cmp::max, ops::Deref, sync::Arc};
|
20
|
+
use tracing::{info, instrument};
|
21
|
+
|
22
|
+
static DEFAULT_BIND: &str = "localhost:3000";
|
25
23
|
|
26
24
|
#[magnus::wrap(class = "Itsi::Server", free_immediately, size)]
|
27
|
-
#[derive(
|
25
|
+
#[derive(Clone)]
|
28
26
|
pub struct Server {
|
27
|
+
pub config: Arc<ServerConfig>,
|
28
|
+
}
|
29
|
+
|
30
|
+
impl Deref for Server {
|
31
|
+
type Target = ServerConfig;
|
32
|
+
|
33
|
+
fn deref(&self) -> &Self::Target {
|
34
|
+
&self.config
|
35
|
+
}
|
36
|
+
}
|
37
|
+
type AfterFork = Mutex<Arc<Option<Box<dyn Fn() + Send + Sync>>>>;
|
38
|
+
|
39
|
+
#[derive(Debug)]
|
40
|
+
pub struct ServerConfig {
|
29
41
|
#[debug(skip)]
|
30
|
-
app: Opaque<Value>,
|
42
|
+
pub app: Opaque<Value>,
|
31
43
|
#[allow(unused)]
|
32
|
-
workers:
|
44
|
+
pub workers: u8,
|
33
45
|
#[allow(unused)]
|
34
|
-
threads:
|
46
|
+
pub threads: u8,
|
35
47
|
#[allow(unused)]
|
36
|
-
shutdown_timeout: f64,
|
37
|
-
script_name: String,
|
48
|
+
pub shutdown_timeout: f64,
|
49
|
+
pub script_name: String,
|
38
50
|
pub(crate) binds: Mutex<Vec<Bind>>,
|
51
|
+
#[debug(skip)]
|
52
|
+
pub before_fork: Mutex<Option<Box<dyn FnOnce() + Send + Sync>>>,
|
53
|
+
#[debug(skip)]
|
54
|
+
pub after_fork: AfterFork,
|
55
|
+
pub scheduler_class: Option<String>,
|
56
|
+
pub stream_body: Option<bool>,
|
57
|
+
pub worker_memory_limit: Option<u64>,
|
58
|
+
}
|
59
|
+
|
60
|
+
#[derive(Debug)]
|
61
|
+
pub enum RequestJob {
|
62
|
+
ProcessRequest(ItsiRequest),
|
63
|
+
Shutdown,
|
39
64
|
}
|
40
65
|
|
41
66
|
impl Server {
|
67
|
+
#[instrument(
|
68
|
+
name = "Itsi",
|
69
|
+
parent=None,
|
70
|
+
skip(args),
|
71
|
+
fields(workers = 1, threads = 1, shutdown_timeout = 5)
|
72
|
+
)]
|
42
73
|
pub fn new(args: &[Value]) -> Result<Self> {
|
43
|
-
|
44
|
-
|
45
|
-
|
74
|
+
let scan_args: Args<(), (), (), (), RHash, ()> = scan_args(args)?;
|
75
|
+
|
76
|
+
type ArgSet1 = (
|
77
|
+
Option<u8>,
|
78
|
+
Option<u8>,
|
46
79
|
Option<f64>,
|
47
80
|
Option<String>,
|
48
81
|
Option<Vec<String>>,
|
82
|
+
Option<Proc>,
|
83
|
+
Option<Proc>,
|
84
|
+
Option<String>,
|
85
|
+
Option<bool>,
|
49
86
|
);
|
50
87
|
|
51
|
-
|
52
|
-
|
53
|
-
|
88
|
+
type ArgSet2 = (Option<u64>,);
|
89
|
+
|
90
|
+
let args1: KwArgs<(Value,), ArgSet1, ()> = get_kwargs(
|
91
|
+
scan_args
|
92
|
+
.keywords
|
93
|
+
.funcall::<_, _, RHash>(
|
94
|
+
"slice",
|
95
|
+
(
|
96
|
+
Symbol::new("app"),
|
97
|
+
Symbol::new("workers"),
|
98
|
+
Symbol::new("threads"),
|
99
|
+
Symbol::new("shutdown_timeout"),
|
100
|
+
Symbol::new("script_name"),
|
101
|
+
Symbol::new("binds"),
|
102
|
+
Symbol::new("before_fork"),
|
103
|
+
Symbol::new("after_fork"),
|
104
|
+
Symbol::new("scheduler_class"),
|
105
|
+
Symbol::new("stream_body"),
|
106
|
+
),
|
107
|
+
)
|
108
|
+
.unwrap(),
|
54
109
|
&["app"],
|
55
110
|
&[
|
56
111
|
"workers",
|
@@ -58,125 +113,132 @@ impl Server {
|
|
58
113
|
"shutdown_timeout",
|
59
114
|
"script_name",
|
60
115
|
"binds",
|
116
|
+
"before_fork",
|
117
|
+
"after_fork",
|
118
|
+
"scheduler_class",
|
119
|
+
"stream_body",
|
61
120
|
],
|
62
121
|
)?;
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
122
|
+
|
123
|
+
let args2: KwArgs<(), ArgSet2, ()> = get_kwargs(
|
124
|
+
scan_args
|
125
|
+
.keywords
|
126
|
+
.funcall::<_, _, RHash>("slice", (Symbol::new("worker_memory_limit"),))
|
127
|
+
.unwrap(),
|
128
|
+
&[],
|
129
|
+
&["worker_memory_limit"],
|
130
|
+
)?;
|
131
|
+
|
132
|
+
let config = ServerConfig {
|
133
|
+
app: Opaque::from(args1.required.0),
|
134
|
+
workers: max(args1.optional.0.unwrap_or(1), 1),
|
135
|
+
threads: max(args1.optional.1.unwrap_or(1), 1),
|
136
|
+
shutdown_timeout: args1.optional.2.unwrap_or(5.0),
|
137
|
+
script_name: args1.optional.3.unwrap_or("".to_string()),
|
69
138
|
binds: Mutex::new(
|
70
|
-
|
139
|
+
args1
|
140
|
+
.optional
|
71
141
|
.4
|
72
|
-
.unwrap_or_else(|| vec![
|
142
|
+
.unwrap_or_else(|| vec![DEFAULT_BIND.to_string()])
|
73
143
|
.into_iter()
|
74
|
-
.map(|s| s.parse()
|
75
|
-
.collect()
|
144
|
+
.map(|s| s.parse())
|
145
|
+
.collect::<itsi_error::Result<Vec<Bind>>>()?,
|
76
146
|
),
|
147
|
+
before_fork: Mutex::new(args1.optional.5.map(|p| {
|
148
|
+
let opaque_proc = Opaque::from(p);
|
149
|
+
Box::new(move || {
|
150
|
+
opaque_proc
|
151
|
+
.get_inner_with(&Ruby::get().unwrap())
|
152
|
+
.call::<_, Value>(())
|
153
|
+
.unwrap();
|
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,
|
77
168
|
};
|
78
|
-
Ok(server)
|
79
|
-
}
|
80
169
|
|
81
|
-
|
82
|
-
|
83
|
-
app: Opaque<Value>,
|
84
|
-
script_name: String,
|
85
|
-
listener: Arc<Listener>,
|
86
|
-
addr: SockAddr,
|
87
|
-
) -> itsi_error::Result<Response<BoxBody<Bytes, Infallible>>> {
|
88
|
-
let request = ItsiRequest::build_from(hyper_request, addr, script_name, listener).await;
|
89
|
-
let ruby = Ruby::get().unwrap();
|
90
|
-
let server = ruby.get_inner(&ITSI_SERVER);
|
91
|
-
let response: Result<(u16, HashMap<String, String>, Value)> =
|
92
|
-
server.funcall("call", (app, request));
|
93
|
-
if let Ok((status, headers_raw, body)) = response {
|
94
|
-
let mut body_buf = vec![];
|
95
|
-
for body_chunk in body.enumeratorize("each", ()) {
|
96
|
-
body_buf.push(body_chunk.unwrap().to_string())
|
97
|
-
}
|
98
|
-
body.check_funcall::<_, _, Value>("close", ());
|
99
|
-
let boxed_body = BoxBody::new(body_buf.join(""));
|
100
|
-
let mut response = Response::new(boxed_body);
|
101
|
-
let mut headers = HeaderMap::new();
|
102
|
-
headers_raw.into_iter().for_each(|(key, value)| {
|
103
|
-
let header_name: HeaderName = key.parse().unwrap();
|
104
|
-
headers.insert(header_name, value.parse().unwrap());
|
105
|
-
});
|
106
|
-
*response.headers_mut() = headers;
|
107
|
-
*response.status_mut() = StatusCode::from_u16(status).unwrap();
|
108
|
-
Ok(response)
|
170
|
+
if let Some(scheduler_class) = args1.optional.7 {
|
171
|
+
info!(scheduler_class, fiber_scheduler = true);
|
109
172
|
} else {
|
110
|
-
|
111
|
-
*response.status_mut() = StatusCode::BAD_REQUEST;
|
112
|
-
Ok(response)
|
173
|
+
info!(fiber_scheduler = false);
|
113
174
|
}
|
175
|
+
|
176
|
+
Ok(Server {
|
177
|
+
config: Arc::new(config),
|
178
|
+
})
|
114
179
|
}
|
115
180
|
|
116
|
-
|
117
|
-
|
118
|
-
let
|
119
|
-
.
|
120
|
-
.
|
121
|
-
.
|
122
|
-
.
|
123
|
-
.
|
124
|
-
.
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
script_name.clone(),
|
166
|
-
listener.clone(),
|
167
|
-
addr.clone(),
|
168
|
-
)
|
169
|
-
}),
|
170
|
-
)
|
171
|
-
.await
|
172
|
-
{
|
173
|
-
info!("Closed connection due to: {:?}", e);
|
174
|
-
}
|
175
|
-
});
|
176
|
-
}
|
177
|
-
});
|
181
|
+
#[instrument(name = "Bind", skip_all, fields(binds=format!("{:?}", self.config.binds.lock())))]
|
182
|
+
pub(crate) fn listeners(&self) -> Result<Arc<Vec<Arc<Listener>>>> {
|
183
|
+
let listeners = self
|
184
|
+
.config
|
185
|
+
.binds
|
186
|
+
.lock()
|
187
|
+
.iter()
|
188
|
+
.cloned()
|
189
|
+
.map(Listener::try_from)
|
190
|
+
.collect::<std::result::Result<Vec<Listener>, _>>()?
|
191
|
+
.into_iter()
|
192
|
+
.map(Arc::new)
|
193
|
+
.collect::<Vec<_>>();
|
194
|
+
info!("Bound {:?} listeners", listeners.len());
|
195
|
+
Ok(Arc::new(listeners))
|
196
|
+
}
|
197
|
+
|
198
|
+
pub(crate) fn build_strategy(
|
199
|
+
self,
|
200
|
+
listeners: Arc<Vec<Arc<Listener>>>,
|
201
|
+
) -> Result<ServeStrategy> {
|
202
|
+
let server = Arc::new(self);
|
203
|
+
|
204
|
+
let strategy = if server.config.workers == 1 {
|
205
|
+
ServeStrategy::Single(Arc::new(SingleMode::new(
|
206
|
+
server,
|
207
|
+
listeners,
|
208
|
+
SIGNAL_HANDLER_CHANNEL.0.clone(),
|
209
|
+
)?))
|
210
|
+
} else {
|
211
|
+
ServeStrategy::Cluster(Arc::new(ClusterMode::new(
|
212
|
+
server,
|
213
|
+
listeners,
|
214
|
+
SIGNAL_HANDLER_CHANNEL.0.clone(),
|
215
|
+
)))
|
216
|
+
};
|
217
|
+
Ok(strategy)
|
218
|
+
}
|
219
|
+
|
220
|
+
pub fn start(&self) -> Result<()> {
|
221
|
+
reset_signal_handlers();
|
222
|
+
let rself = self.clone();
|
223
|
+
let listeners = self.listeners()?;
|
224
|
+
let listeners_clone = listeners.clone();
|
225
|
+
call_without_gvl(move || -> Result<()> {
|
226
|
+
let strategy = rself.build_strategy(listeners_clone)?;
|
227
|
+
if let Err(e) = strategy.run() {
|
228
|
+
error!("Error running server: {}", e);
|
229
|
+
strategy.stop()?;
|
178
230
|
}
|
179
|
-
|
180
|
-
|
231
|
+
drop(strategy);
|
232
|
+
Ok(())
|
233
|
+
})?;
|
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
|
+
clear_signal_handlers();
|
242
|
+
Ok(())
|
181
243
|
}
|
182
244
|
}
|