Counting the number of active tasks on a JoinSet

Hi,

I'm trying to achieve the following:

I have two threads, one that creates a million of short-living tasks, and another monitoring thread that reports the current number of tasks that are running.

As the tasks are very short-lived, I'd expect the monitoring thread to report the JoinSet size sometimes growing and sometimes shrinking, and quickly becoming zero active tasks.

But what I see is that It always increases, and it won't decrease the size of running tasks whenever they finish:

Maybe I'm missing some concepts with JoinSets?

Playground => Rust Playground

use std::{sync::Arc, time::Duration};
use tokio::{sync::Mutex, task::JoinSet};

#[tokio::main]
async fn main() {

    let set = Arc::new(Mutex::new(JoinSet::new()));
    let s1 = set.clone();
    tokio::spawn(async move {
        loop {
	        tokio::time::sleep(Duration::from_millis(100)).await;
            let set = s1.lock().await;
            let ntasks = set.len();
            println!("Tasks: {ntasks}");
        }
    });

    let s2 = set.clone();
    let _ = tokio::spawn(async move {
        for _i in 0.. 1_000_000 {
            let mut joinset = s2.lock().await;
            joinset.spawn(async move {
		
	    });
        }
    }).await;

}

I believe that completed tasks in a JoinSet are not removed until you call join_next() or similar. If you want something like JoinSet that automatically evicts finished tasks, try tokio_util::task::TaskTracker.

3 Likes