Skip to content

It will take a long time to turn off the HTTP service #3188

@Cloud33

Description

@Cloud33

Version
List the version(s) of hyper, and any relevant hyper dependency (such as h2 if this is related to HTTP/2).

axum = { version = "0.6.12"}
hyper = {version = "0.14.25"}

Platform
The output of uname -a (UNIX), or version and 32 or 64-bit (Windows)

64-bit (Windows)

Description
Enter your issue details here.
One way to structure the description:

I reported this issue at axumtokio-rs/axum#991, but the shutdown of axum originated from super, so I briefly explained this issue. I made a very simple API derived from the example hello world + Graceful shutdown. If you only start the http server, it will be shut down immediately, which is very fast, but if you have counted a request, it will get stuck here after shutdown:

2023-03-30 17:14:59.9816 TRACE hyper::proto::h1::conn: shut down IO complete
2023-03-30 17:14:59.9818 TRACE mio::poll: deregistering event source from poller
2023-03-30 17:17:34.4422 TRACE hyper::proto::h1::conn: Conn::read_head
2023-03-30 17:17:34.4427 TRACE hyper::proto::h1::io: received 0 bytes
2023-03-30 17:17:34.4430 TRACE hyper::proto::h1::io: parse eof

Total waiting time: 17:14:59 ~ 17:17:34 = 153 s..

2023-03-30 17:14:59.9818 TRACE mio::poll: deregistering event source from poller

[short summary of the bug]

2023-03-30 17:14:59.9785  INFO fly_api: signal received, starting graceful shutdown
2023-03-30 17:14:59.9788 DEBUG hyper::server::shutdown: signal received, starting graceful shutdown
2023-03-30 17:14:59.9791 TRACE mio::poll: deregistering event source from poller
2023-03-30 17:14:59.9792 TRACE hyper::proto::h1::conn: disable_keep_alive; closing idle connection
2023-03-30 17:14:59.9792 TRACE hyper::proto::h1::conn: disable_keep_alive; in-progress connection
2023-03-30 17:14:59.9797 TRACE hyper::proto::h1::conn: State::close()
2023-03-30 17:14:59.9799 TRACE hyper::proto::h1::conn: Conn::read_head
2023-03-30 17:14:59.9802 TRACE hyper::proto::h1::conn: State::close_read()
2023-03-30 17:14:59.9806 TRACE hyper::proto::h1::conn: State::close_write()
2023-03-30 17:14:59.9804 TRACE hyper::proto::h1::conn: flushed({role=server}): State { reading: Init, writing: Init, keep_alive: Disabled }
2023-03-30 17:14:59.9808 TRACE hyper::proto::h1::conn: flushed({role=server}): State { reading: Closed, writing: Closed, keep_alive: Disabled }
2023-03-30 17:14:59.9816 TRACE hyper::proto::h1::conn: shut down IO complete
2023-03-30 17:14:59.9818 TRACE mio::poll: deregistering event source from poller
2023-03-30 17:17:34.4422 TRACE hyper::proto::h1::conn: Conn::read_head
2023-03-30 17:17:34.4427 TRACE hyper::proto::h1::io: received 0 bytes
2023-03-30 17:17:34.4430 TRACE hyper::proto::h1::io: parse eof
2023-03-30 17:17:34.4433 TRACE hyper::proto::h1::conn: State::close_read()
2023-03-30 17:17:34.4436 DEBUG hyper::proto::h1::conn: read eof
2023-03-30 17:17:34.4439 TRACE hyper::proto::h1::conn: State::close_write()
2023-03-30 17:17:34.4442 TRACE hyper::proto::h1::conn: State::close_read()
2023-03-30 17:17:34.4446 TRACE hyper::proto::h1::conn: State::close_write()
2023-03-30 17:17:34.4450 TRACE hyper::proto::h1::conn: flushed({role=server}): State { reading: Closed, writing: Closed, keep_alive: Disabled }
2023-03-30 17:17:34.4456 TRACE hyper::proto::h1::conn: shut down IO complete
2023-03-30 17:17:34.4459 TRACE mio::poll: deregistering event source from poller
2023-03-30 17:17:34.4467  INFO fly_api: close http service
2023-03-30 17:17:34.4471  INFO fly_api: shutdown start
2023-03-30 17:17:34.4474  INFO fly_api: shutdown end

I tried this code:

pub async fn serve(app_port: u16, client: Client) {
    // build our application with a route
    let app = Router::new()
        .route("/", get(handler))
        .layer(Extension(ApiContext { client }))
        .layer(TraceLayer::new_for_http());

    // add a fallback service for handling routes to unknown paths
    let app = app.fallback(handler_404);
    // run it
    let addr = SocketAddr::from(([127, 0, 0, 1], app_port));

    tracing::debug!("listening on {}", addr);
    axum::Server::bind(&addr)
        .serve(app.into_make_service())
        .with_graceful_shutdown(shutdown_signal())
        .await
        .unwrap();
    tracing::info!("close http service");
}

// 404
async fn handler_404(method: Method, uri: Uri) -> impl IntoResponse {
    (
        StatusCode::NOT_FOUND,
        format!("Nothing to see at {} {}", method, uri),
    )
}

async fn handler() -> Html<&'static str> {
    Html("<h1>Hello, World!</h1>")
}

// 关机
async fn shutdown_signal() {
    let ctrl_c = async {
        tokio::signal::ctrl_c()
            .await
            .expect("failed to install Ctrl+C handler");
    };

    #[cfg(unix)]
    let terminate = async {
        tokio::signal::unix::signal(signal::unix::SignalKind::terminate())
            .expect("failed to install signal handler")
            .recv()
            .await;
    };

    #[cfg(not(unix))]
    let terminate = std::future::pending::<()>();

    tokio::select! {
        _ = ctrl_c => {},
        _ = terminate => {},
    }
    tracing::info!("signal received, starting graceful shutdown");
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-bugCategory: bug. Something is wrong. This is bad!

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions