Gracefully terminating tasks

In Tokio, graceful task shutdown is described as using what I and others term a "kill switch" i.e. providing some synchronisation primitive that can be awaited in a select alongside the main thing to be awaited by the task.

I'm curious as to why this is considered as the go-to approach when we might use a simpler JoinSet instead i.e.

let mut set = JoinSet::new();
set.spawn(task);
set.spawn(another_if_needed);
drop(set): // abort all

Any thoughts? Is there something I'm missing about JoinSet as it seems simpler and avoids needing to use a select?

How would you signal a task in the JoinSet?

You drop the JoinSet.

The author appears to be missing what graceful means. What is shown is a way to do clean shutdown. To be graceful you need to add a timeout so program ends even if part hung.

Using drop is classed as unclean.

TaskTracker also adds description of why to use it over JoinSet.

That's about as far from graceful exit as one may imagine.

Kinda like turning off a lamp by dropping a nuke on it. Sure, it may work, it may even be “simple”, but that's not “graceful”!

1 Like

In what way is it not graceful because I don't think this is obvious... Asked another way, what happens when a JoinSet is dropped, or a spawned tasks's handle is aborted?

Take the following code for a task:

let task = tokio::spawn(async move {
    while let Ok(_event) = rx.recv().await {
        // ...
    }
    println!("If aborted, do we get here?");
});

Does the task's future (recv) get cancelled allowing the receiver to represent itself as being closed?

Graceful shutdown is about signaling the system to stop receiving new tasks, and await the ones on flight.

Dropping the JoinSet would cancel all the stored futures.

1 Like

I call that art

Would my task get to drop anything in scope though? Again, the effects of cancellation appears to be ill-defined.

Thanks for the comments. It seems then that what I was actually asking about was ungraceful termination, and whether the JoinSet or aborting the job handle is reasonable, accepting then that we don't get any cleanup opportunity. Thanks again.