Tokio's multithreaded runtime doesn't behave like I expected
I have been trying to debug this issue for a while now, and I can't figure out, what the problem is.
Take this code:
use std::time::Duration;
use sqlx::PgPool;
const DB_URL: &str = "postgres://devuser:devpassword@localhost:5432/devdb";
async fn db_then_compute(pool: PgPool) {
let num: (i32,) = sqlx::query_as("SELECT 1").fetch_one(&pool).await.unwrap();
println!(
"The num was returned: {}, but now, the CPU block will kill multithreading",
num.0
);
println!("Start compute...");
// This would "fix" the issue:
// pool.close().await;
loop {}
}
/// This doesn't cause the issue
async fn http_then_compute() {
let res = reqwest::get("https://google.de").await.unwrap();
let status = res.status();
println!(
"The num was returned: {}, but the CPU block will not kill multithreading",
status.as_u16()
);
loop {}
}
#[tokio::main]
async fn main() {
let pool = sqlx::PgPool::connect(DB_URL).await.unwrap();
tokio::spawn(db_then_compute(pool));
//tokio::spawn(http_then_compute());
loop {
println!("Observer thread, the sleep will never return");
tokio::time::sleep(Duration::from_secs(1)).await;
}
}
I'd expect the Oberserver thread to continue. I know, CPU-bound tasks in async runtimes are not good, but tokio is multithreaded, so I'd assume, as long as I have enough workers, it should still function. For reference, the reqwest task works completely fine. Running one CPU bound task shouldn't starve a multithreaded runtime, right?
First, I thought this was an sqlx issue. It only happens with postgres, not with sqlite. However, I then tested the same thing with deadpool-postgres, and issue is still persistent. So it's not sqlx after all.
Can someone help me with my misunderstanding of tokio's runtime here? What is blocking other tasks from completing here?