Handle suspend and resume

Virtual machines (VMs) can be suspended, resumed, rebooted, and shut down. When any of these events occur, publishers, subscribers, RPC clients, and RPC servers are affected. Figure 1 shows the lifecycle of a service bundle:

Lifecycle of a service bundle

Figure 1. Lifecycle of a service bundle.

The service bundle lifecycle follows this sequence:

  1. The new method is called to create the service bundle.
  2. The lifecycle manager starts the service bundle and, depending on settings in the orchestration configuration, calls on_start.
  3. When the VM stops or suspends and, depending on settings in the orchestration configuration, lifecycle manager calls on_stop. The on_stop function should stop the threads for publishers, subscribers, RPC clients, and RPC servers.
  4. When the VM is resumed, on_start can recreate the threads if the service bundle is configured to be started again by the orchestration configuration.

Create a configuration to handle suspend and resume

The following example shows a configuration to handle suspend and resume:

# Start `auto_start` service bundles when system is started.
state {
    condition {
        or {
            power_state: "ON"
            power_state: "POWER_OFF_EXIT"
            power_state: "SUSPEND_TO_RAM_EXIT"
        }
    }
    groups_states { started: "auto_start" }
}

# Stop `auto_start` service bundles when system is suspending to RAM.
state {
    condition {
        or {
            power_state: "SUSPEND_TO_RAM_ENTER"
            power_state: "WAIT_FOR_FINISH"
            power_state: "SUSPEND_TO_RAM_POST_FINISH"
        }
    }
    groups_states { created: "auto_start" }
}

Where:

  • WAIT_FOR_FINISH is the last power state in which the service bundle should expect software defined vehicle (SDV) agents to be responsive.
  • SUSPEND_TO_RAM_POST_FINISH indicates that SDV agents might be closing or suspending connection to be able to restore them reliably on resume. It's important not to rely on SUSPEND_TO_RAM_POST_FINISH or POWER_OFF_POST_FINISH to call onStop in the service bundle implementation and, instead, rely on SUSPEND_TO_RAM_ENTER, POWER_OFF_ENTER, and WAIT_FOR_FINISH.

Determine service availability

The following example shows how to use the middleware API in your service bundle to determine if a service unit is available:

let mut registration_event_stream =  sdv::mw::clientlib::create_server_registration_event_stream(
        sdv_comms,
        // Descriptor of type sdv::mw::clientlib::rpc_descriptor::client::Descriptor
        // that binds a specific RPC client type to a communication channel.
        client_descriptor,
    )
    .await
    .expect("unable to generate a registration event");

match registration_event_stream.next().await {
            Some(sdv::mw::Availability::Available) => {
                info!("{unit_name} became Available.");
                // Create client/subscriber
            }
            Some(sdv::mw::Availability::Unavailable) => {
                info!("{unit_name} became Unavailable.");
                // Destroy client/subscriber
            }
            None => {
                warn!("Registration event stream for {unit_name} terminated.
                Stopping monitoring for this variant.");
            }
        }

The create_server_registration_event_stream is a middleware API used to create a event called unit_name. This registration event stream is notified when a service unit becomes available.