with tokio::spawn, tokio::time::timeout does not time out promptly? #3847
-
This test fails for me. (Playground link) It's meant to simulate a case where a task is a bit greedy with the CPU, but it calls I've noticed this only happens with How should I understand this behavior? Is there anything I can do to make my task time out more promptly? #[cfg(test)]
mod tests {
use std::sync::atomic::{AtomicUsize, Ordering};
use std::sync::Arc;
use std::time::Duration;
const BUSY: Duration = Duration::from_millis(1);
const TIMEOUT: Duration = Duration::from_millis(3);
async fn busy_task(counter: Arc<AtomicUsize>) {
for _i in 0..1000_usize {
std::thread::sleep(BUSY); // simulate hogging the CPU, but only for a moment
tokio::task::yield_now().await; // should time out
counter.fetch_add(1, Ordering::SeqCst);
}
}
#[tokio::test]
async fn test_slow_timeout_with_spawn() {
let counter = Arc::new(AtomicUsize::new(0));
let result = tokio::spawn(tokio::time::timeout(TIMEOUT, busy_task(counter.clone())))
.await
.expect("task panicked");
if result.is_ok() {
panic!("should have timed out");
}
let nloops = counter.load(Ordering::SeqCst);
assert!(nloops < 10, "expected <10 iterations before timeout, got {}", nloops);
}
} |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 1 reply
-
This is due to the following: tokio/tokio/src/runtime/basic_scheduler.rs Line 113 in d101fea The basic runtime will poll up to 61 futures before it checks the timer or IO drivers.
Well, it's one to two orders of magnitude more than what I suggest using in my blog post on blocking. |
Beta Was this translation helpful? Give feedback.
This is due to the following:
tokio/tokio/src/runtime/basic_scheduler.rs
Line 113 in d101fea
The basic runtime will poll up to 61 futures before it checks the timer or IO drivers.
Well, it's one to two orders of magnitude more than what I suggest using in my blog post on blocking.