【Rust】Axumでスレッドを並列化させて、async関数を実行させたい

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

うおおおおおおおおお、中々良い^^