目前,我正在阅读 Rust 书的最后一章,实现 HTTP 服务器的正常关闭。
现在我想稍微扩展一下逻辑,并在按 Ctrl-c 后触发正常关闭。因此我使用ctrlc crate。
但由于各种借用检查器错误,我无法使其工作:
fn main() {
let listener = TcpListener::bind("127.0.0.1:7878").unwrap();
let pool = ThreadPool::new(4);
ctrlc::set_handler(|| {
// dropping will trigger ThreadPool::drop and gracefully shutdown the running workers
drop(pool); // compile error, variable is moved here
})
.unwrap();
for stream in listener.incoming() {
let stream = stream.unwrap();
pool.execute(|| {
handle_connection(stream);
});
}
}
Run Code Online (Sandbox Code Playgroud)
我尝试了使用Arc<>和附加mpsc 通道的多种方法,但没有成功。
为了使其发挥作用,最佳实践是什么?
我最终得到:
fn main() {
let listener = TcpListener::bind("127.0.0.1:7878").unwrap();
let pool = ThreadPool::new(4);
let (tx, rx) = channel();
ctrlc::set_handler(move || tx.send(()).expect("Could not send signal on channel."))
.expect("Error setting Ctrl-C handler");
for stream in listener.incoming() {
let stream = stream.unwrap();
pool.execute(|| {
handle_connection(stream);
});
match rx.try_recv() {
Ok(_) => break,
Err(_) => continue,
}
}
}
Run Code Online (Sandbox Code Playgroud)
但它有一个缺陷。即按 Ctrl-c 后,不会立即触发关闭过程,而是在收到另一个请求后才触发。然后循环将中断,ThreadPool 超出范围并被丢弃,从而触发正常关闭逻辑。
该解决方案足以满足我的学习目的。在生产环境中,人们会依赖像actix这样的 Web 框架的正常关闭
| 归档时间: |
|
| 查看次数: |
2010 次 |
| 最近记录: |