`.await` in a #[query] function

I’m integrating Turso database in my canister and it requires database calls to be async

#[query]
async fn query_something() -> Vec<String> {
    with_connection(async |c| {
        Something::query_all(&c).await
    })
    .await
    .expect("failed to read all")
}

This fails with:

Canister called `ic0.trap` with message: 'Panicked at 'protected task outlived its canister method (did you mean to use spawn_weak or spawn_migratory?)'

If I change query to update then all is good. Is there a way to call async functions from query functions? In this case, the async is just how the API works and under the hood, it’s just calling stable storage

If (and only if) there is no true asynchrony occurring, you can call futures::executor::block_on.

What are consequences of getting my assumption of no no true asynchrony happening wrong?

The only source of true asynchrony on the IC is inter-canister calls. If you aren’t making one internally, it isn’t truly async; and if you make one and try to block on it, you will get a trap saying that you exceeded the instruction limit (or that you failed to reply).

1 Like