mod common;
use atap::{
Runtime,
sleep::{Sleep, SleepMode},
};
use common::cores;
use std::{
thread,
time::{Duration, Instant},
};
#[test]
fn pool_grows_under_blocking_load() {
let _ = Runtime::init();
let tasks = cores() * 4;
let duration = Duration::from_millis(400);
let started = Instant::now();
let handles: Vec<_> = (0..tasks)
.map(|_| Runtime::task(Sleep::sleep(duration).mode(SleepMode::Relaxed)).spawn())
.collect();
thread::sleep(Duration::from_millis(100));
let stats = Runtime::pool();
println!(
"{} blocking tasks got {} sleep threads, {} busy, {} still queued",
tasks,
stats.sleep_threads(),
stats.sleep_busy(),
stats.blocking_queued(),
);
let mut slept = Duration::ZERO;
for handle in handles {
slept += handle.join().expect("every task finishes");
}
let elapsed = started.elapsed();
println!(
"{} blocking sleeps of {:?} took {:?}, {:?} slept between them",
tasks, duration, elapsed, slept,
);
assert!(
stats.sleep_threads() >= tasks / 2,
"{} blocking tasks in flight got only {} threads",
tasks,
stats.sleep_threads(),
);
assert!(
slept > elapsed * 2,
"{} blocking sleeps took {:?} of wall clock but only {:?} between them, \
so they were barely overlapping",
tasks,
elapsed,
slept,
);
}