Promise concurrency "await in parallel"

In JavaScript / on the web I can batch promises.

await Promise.all([call1(), call2(), call3()]);

Is there something equivalent in Rust and on the IC to perform multiple call in parallel?

I would like to query the status of multiple canisters not in a row but, in a single batch.

// Something like
let promises = Vec::from([canister_status({CanisterIdRecord { canister_id_1}), canister_status({CanisterIdRecord { canister_id_2})]);
call(promises).await;

RTFM David, Rust noob question :sweat_smile:.

Kind of:

join === Promise.allSettled
try_join === Promise.all

use futures::join;
use ic_cdk::api::management_canister::main::{
    canister_status, CanisterIdRecord, CanisterStatusResponse,
};
use ic_cdk::export::candid::{candid_method, export_service};
use ic_cdk::{id};

#[candid_method(update)]
#[ic_cdk_macros::update]
async fn hello() {
    join!(status(), status(), status());
}

async fn status() -> Result<CanisterStatusResponse, String> {
    let status = canister_status(CanisterIdRecord { canister_id: id() }).await;

    match status {
        Ok((status,)) => Ok(status),
        Err((_, message)) => Err(["Cannot get canister status: ".to_string(), message].join("")),
    }
}

https://rust-lang.github.io/async-book/06_multiple_futures/02_join.html

2 Likes

It does seem like you might need some kind of IC specific implementation here. I run into issues where if I don’t know wait after so many futures in motoko that I run out of the cycle limit. Usually I batch them in groups of nine. I don’t do much rust, so I’m not sure how that works there, but I would imagine that you’d run into a similar situation if you don’t actually await, and you overrun a certain cycle threshold.

1 Like

Good input, thanks for the share! Indeed probably same limitation, join_all takes a vector as parameter so I’ll try to batch them too.

I find this thread helpful Can I run multiple inter-canister update calls in parallel? - #2 by free.

1 Like