How to determine if the canister has stopped and it is safe to upgrade

I want to safely upgrade the canister. To perform that operation I am trying to stop a canister before sending in the upgrade request. According to the reference the ic method stop_canister sends the request to stop a canister but that doesn’t mean the canister will be in stopped state after calling it programmatically. To be sure the canister has stopped I have a loop to check if the canister is stopped and I can perform upgrades. Which looks kind of a hacky version. Is there a better way to do the same?

stop_canister(CanisterIdRecord {canister_id: canister_id.clone()}).await?;
    loop {
        let (canister_status, ) = canister_status(CanisterIdRecord {canister_id: canister_id.clone()}).await.unwrap();
        match canister_status.status {
            CanisterStatusType::Stopped => break,
            _ => ic_cdk::println!("Canister {:?} is stopping", &canister_id)
        }
    } 

// peform upgrades.
1 Like

Hi @gravity_vi, Like it says in the spec, the management canister stop_canister method will send back a response only after the canister is stopped. So there is no need to do that loop. Once the response for the stop_canister call comes back, you can know that the canister is stopped.

After sending the request to stop_canister it doesn’t mean the canister is stopped but after receiving the response to the stop_canister method, it does mean the canister is stopped.

1 Like