Difference between loop + if let Some or while let Some in a tokio::test -> spawn -> spawn_blocking #7718
-
|
If someone could be so kind to explain to me, what happens here, this would be highly appreciated. I would also be happy to be just sent documentation I can read myself to understand. I have read the tokio documentation on its website and the Rust async book but maybe I have forgotten an imported part.
use tokio::sync::mpsc::{self, Receiver, Sender};
#[tokio::main]
async fn main() {
run_app().await;
}
async fn run_app() -> Result<(), ()> {
let (worker, sender) = StorageWorker::new();
let handle = tokio::task::spawn_blocking(|| worker.run().unwrap());
panic!("hi")
}
pub struct StorageWorker {
receiver: Receiver<u32>,
}
impl StorageWorker {
pub fn new() -> (Self, Sender<u32>) {
let (sender, receiver) = mpsc::channel(20);
(StorageWorker { receiver }, sender)
}
fn run(mut self) -> Result<(), ()> {
loop {
if let Some(me) = self.receiver.blocking_recv() {}
}
Ok(())
}
}
...
fn run(mut self) -> Result<(), ()> {
loop {
if let Some(me) = self.receiver.blocking_recv() {}
}
Ok(())
}
}
#[cfg(test)]
mod tests {
use tokio::fs;
use super::*;
#[tokio::test]
async fn it_works() {
tokio::spawn(async {
run_app().await.unwrap();
});
let content = fs::read("test.file").await.unwrap();
}
}
...
fn run(mut self) -> Result<(), ()> {
while let Some(me) = self.receiver.blocking_recv() {}
Ok(())
}
}
#[cfg(test)]
mod tests {
use tokio::fs;
use super::*;
#[tokio::test]
async fn it_works() {
tokio::spawn(async {
run_app().await.unwrap();
});
let content = fs::read("test.file").await.unwrap();
}
}If I replace |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 2 replies
-
|
The example (1) also hangs forever on my side, see https://play.rust-lang.org/?version=stable&mode=debug&edition=2024&gist=f09245299756bbc0838bcc56ea547342. The reason example (1) hangs forever is that it shuts down the blocking thread pool. However, the blocking task itself hangs forever, so the shutdown process also hangs forever. See also By default, In example (3), the |
Beta Was this translation helpful? Give feedback.
The example (1) also hangs forever on my side, see https://play.rust-lang.org/?version=stable&mode=debug&edition=2024&gist=f09245299756bbc0838bcc56ea547342.
The reason example (1) hangs forever is that it shuts down the blocking thread pool. However, the blocking task itself hangs forever, so the shutdown process also hangs forever. See also
Runtime::shutdown_backgroundandRuntime::shutdown_timeout.By default,
[tokio::test]uses the current-thread runtime instead of the multi-thread runtime. Sincerun_app().awaitnever resolves, example (2) also hangs forever.In example (3), the
sendergets dropped due to thepanic!, which causes thereceiverto close, and finallyrun_app().awaitresol…