关闭具有多个运行系统的actix

时间:2019-02-07 09:13:54

标签: rust rust-actix

我的应用程序基于使用actix和actix-web的库(Library-A)。我要添加第二个库(Library-B),它也使用actix-web运行http服务器。我为此使用了单独的线程和actix::system。在SIGINT上,只有Library-B actix系统关闭,而Library-A仍在运行。随后没有SIGINT会关闭正在运行的actix系统。

正常关闭两个正在运行的actix系统的正确方法是什么?

库B的代码,用于启动新的actix系统并运行http服务器:

thread::spawn(move || {
    let sys = actix::System::new("monitor");
    server::new(|| App::new()
        .route("/metrics", http::Method::GET, endpoint))
        .bind(format!("0.0.0.0:{}", port))
        .unwrap()
        .start();
    sys.run();
    println!("Closing monitor actix system");
    // --- SIGINT gets me here... how do I shut down gracefully?
});

为我的独立图书馆启动新系统对吗?如何正常关闭?

1 个答案:

答案 0 :(得分:1)

使用ctrlc条板箱可以捕获Ctrl+C信号。

主线程的用法可以在Rust-Lang-Nursery

中找到

由于您是从主线程创建线程的,并且在捕获主线程中的信号之后,因此您可以通过观察这些线程中的共享布尔值来正常关闭其他线程。

此外,还有stop功能专门针对Actix。

您还可以使用chan-signal crate并编写您的自定义实现,例如已回答的here

创建自己的关机逻辑

在所有线程中检查共享的Arc原子布尔值,并在主线程中更改此变量后停止执行。由于您在主线程上捕获了ctrl-c信号,因此它可以通知其他actor线程,如下所示:

use ctrlc;
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::Arc;
use std::thread;

fn main() {
    let running = Arc::new(AtomicBool::new(true));
    let running2 = running.clone();
    let r = running.clone();

    let thandle = thread::spawn(move || {
        while running2.load(Ordering::Relaxed) {
            //Do your logic here
        }
        println!("Thread1 stopped.")
    });

    let thandle2 = thread::spawn(move || {
        while running.load(Ordering::Relaxed) {
            //Do your different logic here
        }
        println!("Thread2 stopped.")
    });

    ctrlc::set_handler(move || {
        r.store(false, Ordering::Relaxed);
    })
    .expect("Error setting Ctrl-C handler");

    println!("Waiting for Ctrl-C...");
    let _ = thandle.join();
    let _ = thandle2.join();
}