axumでPostされたデータの処理で重い処理があるため、スレッドで並列化させて、先にURLを表示させたい時。
### ダメな例(asyncでない関数を呼び出す)
これでも動くのは動く(先にレンダリングされる)が、spawnの中の関数は、asyncは使えない。
async fn handle_index() -> axum::response::Html<String> { let handle = std::thread::spawn(move||{ let _ = delay(); }); println!("main thread"); let tera = tera::Tera::new("templates/*").unwrap(); let mut context = tera::Context::new(); context.insert("title", "Index page"); let output = tera.render("index.html", &context); return axum::response::Html(output.unwrap()) handle.join().unwrap(); } fn delay() { thread::sleep(Duration::from_secs(2)); println!("sub thread"); }
Finished `dev` profile [unoptimized + debuginfo] target(s) in 6.65s
Running `target/debug/axum`
main thread
sub thread
### asyncで並列化
tokio::spawn で、別スレッドでasync関数を実行することができる。handle.joinの記述も不要。
async fn handle_index() -> axum::response::Html<String> { let handle = tokio::spawn(async move { let _ = delay().await; }); println!("main thread"); let tera = tera::Tera::new("templates/*").unwrap(); let mut context = tera::Context::new(); context.insert("title", "Index page"); let output = tera.render("index.html", &context); return axum::response::Html(output.unwrap()); } async fn delay() { thread::sleep(Duration::from_secs(2)); println!("sub thread"); }
Finished `dev` profile [unoptimized + debuginfo] target(s) in 6.65s
Running `target/debug/axum`
main thread
sub thread
うおおおおおおおおお、中々良い^^