seanmonstar / warp

A super-easy, composable, web server framework for warp speeds.
https://seanmonstar.com/post/176530511587/warp
MIT License
9.59k stars 723 forks source link

Gracefull shutdown not working #870

Open karlbom opened 3 years ago

karlbom commented 3 years ago

Version

└── warp v0.3.1

Platform Darwin ####-MBP.##### 20.5.0 Darwin Kernel Version 20.5.0: Sat May 8 05:10:33 PDT 2021; root:xnu-7195.121.3~9/RELEASE_X86_64 x86_64

Description Graceful shutdown not working correctly, if the server sample code is started and no request is made the server will shutdown as expected. If a request or is made during that time e.g. http://localhost:8080 opened in a browser (in my case Chrome) the server will not shutdown unless Chrome is closed or the tab is reloaded after the shutdown was initiated.

I tried this code:

use std::{thread, time::Duration};
use tokio::sync::oneshot;
use warp::Filter;

#[tokio::main]
async fn main() {
    let (shutdown_tx, shutdown_rx) = oneshot::channel();

    let web_thread = tokio::spawn(async {
        let index = warp::path::end().map(|| "Hello world");
        println!("Webserver thread starting");
        let (_, server) =
            warp::serve(index).bind_with_graceful_shutdown(([0, 0, 0, 0], 8080), async {
                shutdown_rx.await.ok();

            });
        server.await;
        println!("Webserver thread stopped");
    });

    // Let server run for some time - please make a few Http calls now! :)
    thread::sleep(Duration::from_secs(10));

    println!("Requesting shutdown...");
    shutdown_tx.send(()).expect("shutdown webserver");
    web_thread.await;
    println!("done");
}

The issue seems similar to #290 , I lifted the example code from that issue

jxs commented 3 years ago

Hi, I couldn't reproduce the bug you describe with the example you provided. Are you sure you are using warp 0.3.1?

ben186 commented 3 years ago

Same, the server won't shut down when I use localhost. However, accessing through 127.0.0.1 is fine though.

(using warp 0.3.1)

deftsp commented 3 years ago

Same. warp 0.3.1, bind to "0.0.0.0", shutdown can not work randomly.

adumbidiot commented 2 years ago

Seems like intended behavior: https://github.com/hyperium/hyper/issues/1885

farcaller commented 2 years ago

I stumbled upon this today and I was unpleasantly surprised with this behavior. One alternative though is to select over the shutdown future and the webserver:

let webserver = warp::serve(routes).bind_with_graceful_shutdown(addr, shutdown.clone().boxed()).boxed();
let delayed_shutdown = shutdown
    .then(|_| async move {
        sleep(Duration::from_secs(5)).await;
    })
    .boxed();

select_all(vec![webserver, delayed_shutdown]).await;

This way you ask warp to shut down gracefully but if it can't then you just drop it on the floor after a timeout.