如何启动火箭服务器和其他东西?

jac*_*ack 5 rust-rocket

基本上我希望有一个进程同时处理多个事情(特别是希望有一个http端点来监视非http服务),但似乎我陷入了Rocket,具体取决于火箭特定的tokio运行时,我不知道如何解决这个问题。我曾考虑过让 Rocket 作为主要入口点,而不是 tokio 的标准入口点,并从该运行时启动其他东西,但这似乎是错误的,而且很脆弱,因为我可能会切换库。我考虑过使用 hyper 和 warp,并且我有点自信我可以让它们在这种情况下工作,但我想使用 Rocket,因为我在这个项目的其他地方使用它。我使用的是0.5-rc01版本。

来自文档:

Rocket v0.5 uses the tokio runtime. The runtime is started for you if you use #[launch] or #[rocket::main], but you can still launch() a Rocket instance on a custom-built runtime by not using either attribute.
Run Code Online (Sandbox Code Playgroud)

不幸的是,我找不到任何关于此定制运行时的要求的进一步解释,也找不到任何不使用启动/主宏的示例。

这是我尝试使用的代码的简化版本:

#[rocket::get("/ex")]
async fn test() -> &'static str {
    "OK"
}

#[tokio::main]
async fn main() {
    tokio::spawn(async {
        let config = Config {
            port: 8001,
            address: std::net::Ipv4Addr::new(127, 0, 0, 1).into(),
            ..Config::debug_default()
        };

        rocket::custom(&config)
            .mount("/", rocket::routes![test])
            .launch()
            .await;
    });

    let start = Instant::now();
    let mut interval = interval_at(start, tokio::time::Duration::from_secs(5));

    loop {
        interval.tick().await;
        println!("Other scheduled work");
    }
}
Run Code Online (Sandbox Code Playgroud)

当我按 CTRL-C 终止进程时,会打印以下内容:

^CWarning: Received SIGINT. Requesting shutdown.
Received shutdown request. Waiting for pending I/O...
Warning: Server failed to shutdown cooperatively.
   >> Server is executing inside of a custom runtime.
   >> Rocket's runtime is `#[rocket::main]` or `#[launch]`.
   >> Refusing to terminate runaway custom runtime.
Other scheduled work
Other scheduled work
Other scheduled work
Run Code Online (Sandbox Code Playgroud)

我发现此文档解释了如果您使用自定义运行时,则需要在关闭时“合作”,但它没有解释合作需要什么。另外,在生成的线程中运行 Rocket 之外的东西会导致 CTRL-C 终止进程,正如我通常预期的那样,所以我认为这与 Rocket 特别相关。我需要做什么才能真正终止该进程?

编辑:我放弃并改用扭曲,这要容易一千倍。我仍然很想知道用火箭做到这一点的正确方法,如果有人有建议,我会再试一次。

Mat*_*mer 1

我认为你可以让 Rocket 负责启动你的 tokio 运行时:

#[rocket::main]
async fn main() {
    tokio::spawn(async {
        let start = Instant::now();
        let mut interval = interval_at(start, tokio::time::Duration::from_secs(5));

        loop {
            interval.tick().await;
            println!("Other scheduled work");
        }
    });

    let config = Config {
        port: 8001,
        address: std::net::Ipv4Addr::new(127, 0, 0, 1).into(),
        ..Config::debug_default()
    };

    rocket::custom(&config)
        .mount("/", rocket::routes![test])
        .launch()
        .await;
}
Run Code Online (Sandbox Code Playgroud)

您可以在您生成的任务中完成您自己的额外逻辑,并且火箭以正常方式发射。