根据Rust的要求杀死Warp Web服务器

发布于 2025-02-06 20:32:05 字数 925 浏览 1 评论 0 原文

我正在学习生锈,我想做的就是杀死或关闭 get /< /code>上的Web服务器。

这是您无法使用经纱做的事情吗?还是我的实施破坏了?

我有以下代码,但似乎不想响应任何HTTP请求。

pub async fn perform_oauth_flow(&self) {
        let (tx, rx) = channel::unbounded();

        let routes = warp::path::end().map(move || {
            println!("handling");
            tx.send("kill");
            Ok(warp::reply::with_status("OK", http::StatusCode::CREATED))
        });

        println!("Spawning server");
        let webserver_thread = thread::spawn(|| async {
            spawn(warp::serve(routes).bind(([127, 0, 0, 1], 3000)))
                .await
                .unwrap();
        });

        println!("waiting for result");
        let result = rx.recv().unwrap();
        println!("Got result");
        if result == "kill" {
            webserver_thread.join().unwrap().await;
        }
    }

I'm learning rust and for something that I want to do is kill, or shutdown, a webserver on GET /.

Is this something you can't do in with warp? Or is my implementation broken?

I've got the following code, but it just doesn't seem to want to respond to any HTTP requests.

pub async fn perform_oauth_flow(&self) {
        let (tx, rx) = channel::unbounded();

        let routes = warp::path::end().map(move || {
            println!("handling");
            tx.send("kill");
            Ok(warp::reply::with_status("OK", http::StatusCode::CREATED))
        });

        println!("Spawning server");
        let webserver_thread = thread::spawn(|| async {
            spawn(warp::serve(routes).bind(([127, 0, 0, 1], 3000)))
                .await
                .unwrap();
        });

        println!("waiting for result");
        let result = rx.recv().unwrap();
        println!("Got result");
        if result == "kill" {
            webserver_thread.join().unwrap().await;
        }
    }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

带上头具痛哭 2025-02-13 20:32:05
let webserver_thread = thread::spawn(|| async {
//                                      ^^^^^

创建 async 块不会在内部执行代码;它只是创建未来您需要 .await 。您的服务器实际上从未运行。

通常,使用与异步代码的线程无法正常工作。最好使用您的运行时任务,如果 warp tokio ,使用 tokio :: spawn(Spawn()

let webserver_thread = tokio::spawn(async move {
    spawn(warp::serve(routes).bind(([127, 0, 0, 1], 3000)))
        .await
        .unwrap();
});

// ...

if result == "kill" {
    webserver_thread.await;
}

您也可能会发现有必要使用而不是同步通道。

let webserver_thread = thread::spawn(|| async {
//                                      ^^^^^

Creating an async block is not going to execute the code inside; it is just creating a Future you need to .await. Your server never actually runs.

In general, using threads with async code is not going to work well. Better to use your runtime tasks, in case of warp it is tokio, using tokio::spawn():

let webserver_thread = tokio::spawn(async move {
    spawn(warp::serve(routes).bind(([127, 0, 0, 1], 3000)))
        .await
        .unwrap();
});

// ...

if result == "kill" {
    webserver_thread.await;
}

You may also find it necessary to use tokio's async channels instead of synchronous channels.

吾性傲以野 2025-02-13 20:32:05

您的代码中有两个问题:

  1. @chayimfriedman的答案,您永远不会启动服务器运行。
  2. 即使您用Tokio任务替换线程,也永远不会告诉服务器退出。您需要使用,以便您可以通知服务器退出。

(未经测试)完整示例:

pub async fn perform_oauth_flow(&self) {
    let (tx, rx) = tokio::oneshot::channel();

    let routes = warp::path::end().map(move || {
        println!("handling");
        tx.send(());
        Ok(warp::reply::with_status("OK", http::StatusCode::CREATED))
    });

    println!("Spawning server");
    let server = warp::serve(routes)
               .bind_with_graceful_shutdown(
                   ([127, 0, 0, 1], 3000)),
                   async { rx.await.ok(); })
               .1;

    println!("waiting for result");
    server.await;
}

There are two issues in your code:

  1. As pointed out by @ChayimFriedman's answer, you never start the server because your async block never runs.
  2. Even if you replace the threads with Tokio tasks, you never tell the server to exit. You need to use bind_with_graceful_shutdown so that you can notify the server to exit.

(Untested) complete example:

pub async fn perform_oauth_flow(&self) {
    let (tx, rx) = tokio::oneshot::channel();

    let routes = warp::path::end().map(move || {
        println!("handling");
        tx.send(());
        Ok(warp::reply::with_status("OK", http::StatusCode::CREATED))
    });

    println!("Spawning server");
    let server = warp::serve(routes)
               .bind_with_graceful_shutdown(
                   ([127, 0, 0, 1], 3000)),
                   async { rx.await.ok(); })
               .1;

    println!("waiting for result");
    server.await;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文