Skip to content

[bug] handle.dump() Causes multi_thread issues (partially working or all sleeping) #7478

@duskfeng

Description

@duskfeng

Version
1.33.0/1.46.1

Platform
Linux

Description

[short summary of the bug]
handel.dump() Causes the mutil_thread not work properly (partially working or all sleeping)
I originally had four threads working normally, only part of the threads worked after executing dump, and they didn't even work
I tried this code:

use dashmap::DashMap;
use futures::future::join_all;
use std::sync::Arc;
use std::thread;
use std::time::Duration;
use tokio::time::timeout;

fn main() {
    let rt = tokio::runtime::Builder::new_multi_thread().enable_all().build().unwrap();
    let handle = rt.handle().clone();
    println!("--- Phase 1 ---");
    rt.block_on(async {
        let stats1 = Arc::new(DashMap::new());
        run_test_batch(stats1.clone(), 1000).await;
        print_stats("Stats before dump()", &stats1, 1000);
    });

    let _dump_data = rt.block_on(async {
        let d = timeout(Duration::new(5, 0), handle.dump()).await;
        println!("{:?}", d.unwrap())
    });

    println!("\n--- Phase 3 ---");
    rt.block_on(async {
        let stats2 = Arc::new(DashMap::new());
        run_test_batch(stats2.clone(), 1000).await;
        print_stats("Stats after dump()", &stats2, 1000);
    });
    println!("This will also never be printed.");
}

async fn run_test_batch(stats: Arc<DashMap<thread::ThreadId, usize>>, num_tasks: usize) {
    let mut join_handles = Vec::with_capacity(num_tasks);
    for _ in 0..num_tasks {
        let stats_clone = stats.clone();
        join_handles.push(tokio::spawn(async move {
            //tokio::task::yield_now().await;
            let tid = thread::current().id();
            *stats_clone.entry(tid).or_insert(0) += 1;
        }));
    }

    println!("check inject len");
    join_all(join_handles).await;
}

fn print_stats(title: &str, stats: &DashMap<thread::ThreadId, usize>, expected_tasks: usize) {
    println!("{}", title);
    let mut total_tasks = 0;
    for entry in stats.iter() {
        println!("  - Thread {:?}: ran {} tasks", entry.key(), entry.value());
        total_tasks += *entry.value();
    }
    println!("  Total tasks executed: {}", total_tasks);
    assert_eq!(total_tasks, expected_tasks, "Task count mismatch!");
}

[code sample that causes the bug]

let _dump_data = rt.block_on(async {
        let d = timeout(Duration::new(5, 0), handle.dump()).await;
    });

I expected to see this happen: [explanation]

Image

Instead, this happened: [explanation]

partially working
Image
all sleeping
Image

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-tokioArea: The main tokio crateC-bugCategory: This is a bug.M-taskdump--cfg tokio_taskdump

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions