New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Server does not clean up resources after calling ServerHandle::stop in certain cases #2759
Comments
Edit: Applied the workaround from #2739 (comment) and actix is now shutting down gracefully after a few seconds. @julianskartor did you find a workaround since submitting the issue? I've hit the same symptom of hanging on shutdown after spawning a pair of mpsc. A single channel shuts down fine, but not 2, each rx in their respective spawned block. |
@gxtaillon no there is no real workaround for this that I have found. Luckily the condition for the bug is rare (only if handler is very long running) so we don't experience this in practice. We also have infrastructure to handle this if it would happen (e.g. stop forwarding new requests to the service). |
I'm also seeing something like this. When running my application in kubernetes it never shuts down. However I haven't been able to reproduce locally. My first thought was that this is something to do with connection keepalive but that doesn't seem to be the case. At least the simple case of HTTP/1.1 pipelining doesn't appear to keep the connection open. % nc localhost 8000 <<<$'GET / HTTP/1.1\r\nContent-Length:2\r\n\r\nhi\r\n' I didn't manage to find a good test for HTTP/2. However I don't think ingress-nginx should be using HTTP/2 so that is probably not the problem anyways. My code looks something like this: let server = actix_web::HttpServer::new(move || {
actix_web::App::new()
.default_service(actix_web::web::to(handle))
})
.bind("0.0.0.0:8000")).unwrap()
.disable_signals()
.run();
let server_handle = server.handle();
let server = tokio::spawn(server);
let mut sigterm = tokio::signal::unix::signal(tokio::signal::unix::SignalKind::terminate()).unwrap();
tokio::select! {
r = server => tracing::warn!(
error = ?r.as_ref().err(),
"http server exited {:#?}", r),
_ = sigterm.recv() => tracing::info!("SIGTERM received, exiting."),
() = run_forever(&global, crate::some_background_job) => unreachable!(),
() = run_forever(&global, crate::other_background_job) => unreachable!(),
};
server_handle.stop(true).await; But even after the last line I can make new requests and the resources associated are never released. (Which prevents the server from shutting down for other reasons). |
If a service takes long time to complete (longer than value specified by
HttpServer::shutdown_timeout
to be precise), it seems the server does not properly clean up after itself. In particular, I have an issue with this when the server holds on to a tokio channel sender and I'm waiting for the channel's receiver to get "channel closed" message in a separate tokio task after stopping the server.Expected Behavior
After calling
ServerHandle::stop
and waiting until the end of theshutdown_timeout
period, all resources held by the server should be dropped.Current Behavior
Server seems to still hold on to resources.
Possible Solution
None known...
Steps to Reproduce (for bugs)
Given the following example application:
When I call
curl -X POST localhost:20000/sleep10
and sendSIGINT
to the application, it cleanly shutsdown (OK).If I call
curl -X POST localhost:20000/sleep30
and sendSIGINT
, the application never terminates (BUG).Context
The end goal for me is to implement graceful shutdown of my application that also runs some other tokio
spawn
ed andspawn_blocking
tasks.Your Environment
The text was updated successfully, but these errors were encountered: