What happens when I use `ic_cdk::spawn` in an IC canister and then panic after?

43 Views Asked by At

If I have something like this, and I call test, will the async call to test_2 be made?

#[update]
async fn test() {
    println!("test was called");
    ic_cdk::spawn(async move {
        let _: () = ic_cdk::call(ic_cdk::api::id(), "test_2", ()).await.unwrap();
    });
    panic!("Panic at the disco!");
}

#[update]
async fn test_2() {
    println!("Playground canister test_2 was called");
}
1

There are 1 best solutions below

0
On

I was able to run this with a StateMachine test:

use dfn_candid::candid_one;
use ic_base_types::PrincipalId;
use ic_nns_test_utils::state_test_helpers::{create_canister, update_with_sender};
use ic_state_machine_tests::StateMachine;
use std::time::Duration;

#[test]
fn test_canister_playground() {
    let state_machine = StateMachine::new();

    let canister_playground_wasm =
        Project::cargo_bin_maybe_from_env("canister-playground-canister", &[]);

    let playground_id =
        create_canister(&state_machine, canister_playground_wasm, Some(vec![]), None);

    let response: () = update_with_sender(
        &state_machine,
        playground_id,
        "test",
        candid_one,
        (),
        PrincipalId::new_anonymous(),
    )
    .unwrap();

    // Up to 10 seconds of excitement
    for _ in 1..100 {
        state_machine.tick();
        state_machine.advance_time(Duration::from_millis(100))
    }

    println!("Response: {:?}", response);
}

I got the following output:

2021-05-06 19:17:10 UTC: [Canister rwlgt-iiaaa-aaaaa-aaaaa-cai] Playground Canister Init!
2021-05-06 19:17:12 UTC: [Canister rwlgt-iiaaa-aaaaa-aaaaa-cai] Playground test was called
2021-05-06 19:17:12 UTC: [Canister rwlgt-iiaaa-aaaaa-aaaaa-cai] Playground test - spawns were called
2021-05-06 19:17:12 UTC: [Canister rwlgt-iiaaa-aaaaa-aaaaa-cai] Panicked at 'Panic at the disco!', rs/nns/integration_tests/test_canisters/canister_playground_canister.rs:38:5

It appears that panicking prevents the spawn call from finishing execution, as the state is rolled back after panic (and part of the state was that the call was going to run later).