Graceful shutdown of a tokio-based server #1819
Replies: 5 comments 1 reply
-
Hey @dominiquelefevre, Gracefully cancelling a future is one of the pain points for me when using Rust's async and tokio. I haven't read a lot of tokio/async code so I don't know how people do this in general, but the pattern I developed is I share a one-shot "stop now" channel or some other channel that can receive a "stop now" message with my tasks, and then use a Here are a few examples:
It's a painful and verbose process, but that's the only way that I know for gracefully cancelling tasks.
My understanding is that tokio owns the tasks, but you can have futures in those tasks that you It's possible that I'm misunderstanding this though. |
Beta Was this translation helpful? Give feedback.
-
Relates to #1879. |
Beta Was this translation helpful? Give feedback.
-
Basically, graceful server shutdown is something we need to figure out how we want to handle API wise. We could add a The linked issue above describes some potential strategies to model structured spawn where the child task is spawned w/ a cancellation handle that it can use to gracefully shutdown. |
Beta Was this translation helpful? Give feedback.
-
Hi. Just a heads-up: with easier task cancelation in mind, I recently contributed |
Beta Was this translation helpful? Give feedback.
-
I have converted this to a Discussion. Also worth noting that the Mini-Redis example shows how to do graceful shutdown: https://github.com/tokio-rs/mini-redis#graceful-shutdown |
Beta Was this translation helpful? Give feedback.
-
Hi,
let us consider a server that spawns a task per each client connection, like the example echo server:
Suppose that handlers of client requests may use pooled resources like db connections.
Now I want to add graceful shutdown to such server. I want to
if I read https://internals.rust-lang.org/t/async-await-the-challenges-besides-syntax-cancellation/10287 correctly, the way to cancel a future is to drop it, which is incompatible with tokio's
tokio::spawn(future)
which movesfuture
into tokio's runtime. How am I supposed to stop the listener task gracefully?I can possibly use
futures::drop_notify::drop_notify()
, and code the listener loop like this:But this looks like a lot of boilerplate, and works to cancel a single task only. How to generalise that to canceling many tasks?
P.S. It seems that I am misunderstanding some very basic things about the design of async/await and tokio. That starts with a seemingly contradictive requirements to own a future to cancel it, and to give up the ownership to tokio's runtime to run it. Maybe there is some decent documentation that describes the intended use of async/await with tokio, and typical usage patterns? In particular, I am also interested in propagating context between async tasks to track things like opentracing ids.
Beta Was this translation helpful? Give feedback.
All reactions