vmgs_broker/
lib.rs

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4//! A task + RPC client for interacting with a shared VMGS instance.
5
6#![forbid(unsafe_code)]
7
8mod broker;
9mod client;
10pub mod non_volatile_store;
11pub mod resolver;
12
13pub use client::VmgsClient;
14pub use client::VmgsClientError;
15
16use crate::broker::VmgsBrokerTask;
17use pal_async::task::Spawn;
18use pal_async::task::Task;
19
20/// Given a fully-initialized VMGS instance, return a VMGS broker task +
21/// clonable VmgsClient
22pub fn spawn_vmgs_broker(spawner: impl Spawn, vmgs: vmgs::Vmgs) -> (VmgsClient, Task<()>) {
23    let (control_send, control_recv) = mesh_channel::mpsc_channel();
24
25    let process_loop_handle = spawner.spawn("vmgs-broker", async move {
26        VmgsBrokerTask::new(vmgs).run(control_recv).await
27    });
28
29    (
30        VmgsClient {
31            control: control_send,
32        },
33        process_loop_handle,
34    )
35}
36
37/// A wrapper around [`VmgsClient`] that restricts its API down to operations
38/// that perform no storage IO.
39///
40/// This types is useful for keeping performance-sensitive code "honest" by
41/// making it harder for future refactors to accidentally introduce VMGS IO into
42/// performance hotpaths.
43#[derive(inspect::Inspect)]
44#[inspect(transparent)]
45pub struct VmgsThinClient(VmgsClient);
46
47impl VmgsThinClient {
48    /// Restrict an existing [`VmgsClient`] to only non-IO operations.
49    pub fn new(vmgs_client: VmgsClient) -> Self {
50        Self(vmgs_client)
51    }
52
53    /// See [`VmgsClient::save`]
54    pub async fn save(&self) -> Result<vmgs::save_restore::state::SavedVmgsState, VmgsClientError> {
55        self.0.save().await
56    }
57}