/// Signals a canister to stop.
///
/// If the canister is running, then the canister is marked as "stopping".
/// Stopping is meant to be an ephemeral state where the canister has the
/// opportunity to close its call contexts before fully stopping. The stop
/// message is saved in the canister's status so that, at a later point, the
/// scheduler can respond to that message when the canister is fully
/// stopped.
///
/// If the canister is in the stopping state, then the stop message is
/// appended to the canister's status. At a later point when the canister is
/// ready to be fully stopped, the scheduler will respond to this message.
///
/// If the canister is already stopped, then this function is a no-op.
Signals a canister to stop.
If the canister is running, then the canister is marked as "stopping".
Stopping is meant to be an ephemeral state where the canister has the
opportunity to close its call contexts before fully stopping. The stop
message is saved in the canister's status so that, at a later point, the
scheduler can respond to that message when the canister is fully
stopped.

If the canister is in the stopping state, then the stop message is
appended to the canister's status. At a later point when the canister is
ready to be fully stopped, the scheduler will respond to this message.

If the canister is already stopped, then this function is a no-op.
Signals a canister to stop . If the canister is running then the canister is marked as " stopping " . Stopping is meant to be an ephemeral state where the canister has the opportunity to close its call contexts before fully stopping . The stop message is saved in the canister ' s status so that at a later point the scheduler can respond to that message when the canister is fully stopped . If the canister is in the stopping state then the stop message is appended to the canister ' s status . At a later point when the canister is ready to be fully stopped the scheduler will respond to this message . If the canister is already stopped then this function is a no - op .
pub(crate) fn stop_canister(
        &self,
        canister_id: CanisterId,
        mut stop_context: StopCanisterContext,
        state: &mut ReplicatedState,
    ) -> StopCanisterResult {
        let mut canister = match state.take_canister_state(&canister_id) {
            None => {
                return StopCanisterResult::Failure {
                    error: CanisterManagerError::CanisterNotFound(canister_id),
                    cycles_to_return: stop_context.take_cycles(),
                }
            }
            Some(canister) => canister,
        };
        let result = match self.validate_controller(&canister, stop_context.sender()) {
            Err(err) => StopCanisterResult::Failure {
                error: err,
                cycles_to_return: stop_context.take_cycles(),
            },
            Ok(()) => {
                match &mut canister.system_state.status {
                    CanisterStatus::Stopped => StopCanisterResult::AlreadyStopped {
                        cycles_to_return: stop_context.take_cycles(),
                    },
                    CanisterStatus::Stopping { stop_contexts, .. } => {
                        // Canister is already stopping. Add the message to it
                        // so that we can respond to the message once the
                        // canister has fully stopped.
                        stop_contexts.push(stop_context);
                        StopCanisterResult::RequestAccepted
                    }
                    CanisterStatus::Running {
                        call_context_manager,
                    } => {
                        // Transition the canister into the stopping state.
                        canister.system_state.status = CanisterStatus::Stopping {
                            call_context_manager: call_context_manager.clone(),
                            // Track the stop message to later respond to it once the
                            // canister is fully stopped.
                            stop_contexts: vec![stop_context],
                        };
                        StopCanisterResult::RequestAccepted
                    }
                }
            }
        };
        state.put_canister_state(canister);
        result
    }
pub ( crate ) fn stop_canister ( & self , canister_id : CanisterId , mut stop_context : StopCanisterContext , state : & mut ReplicatedState , ) -> StopCanisterResult { let mut canister = match state . take_canister_state ( & canister_id ) { None => { return StopCanisterResult :: Failure { error : CanisterManagerError :: CanisterNotFound ( canister_id ) , cycles_to_return : stop_context . take_cycles ( ) , } } Some ( canister ) => canister , } ; let result = match self . validate_controller ( & canister , stop_context . sender ( ) ) { Err ( err ) => StopCanisterResult :: Failure { error : err , cycles_to_return : stop_context . take_cycles ( ) , } , Ok ( ( ) ) => { match & mut canister . system_state . status { CanisterStatus :: Stopped => StopCanisterResult :: AlreadyStopped { cycles_to_return : stop_context . take_cycles ( ) , } , CanisterStatus :: Stopping { stop_contexts , .. } => { // Canister is already stopping. Add the message to it // so that we can respond to the message once the // canister has fully stopped. stop_contexts . push ( stop_context ) ; StopCanisterResult :: RequestAccepted } CanisterStatus :: Running { call_context_manager , } => { // Transition the canister into the stopping state. canister . system_state . status = CanisterStatus :: Stopping { call_context_manager : call_context_manager . clone ( ) , // Track the stop message to later respond to it once the // canister is fully stopped. stop_contexts : vec ! [ stop_context ] , } ; StopCanisterResult :: RequestAccepted } } } } ; state . put_canister_state ( canister ) ; result }
Signals a canister to stop.
Signals a canister to stop .
&self
canister_id
CanisterId
stop_context
StopCanisterContext
state
&mut ReplicatedState