Skip to main content

meerkat_runtime/handles/
comms_drain.rs

1//! Runtime impl of [`meerkat_core::handles::CommsDrainHandle`].
2
3use std::sync::Arc;
4
5use meerkat_core::handles::{CommsDrainHandle, DrainExitReason, DrainMode, DslTransitionError};
6
7use super::HandleDslAuthority;
8use crate::meerkat_machine::dsl as mm_dsl;
9
10/// Runtime-backed [`CommsDrainHandle`] impl.
11///
12/// Routes every trait method to the corresponding DSL input / signal on a
13/// dedicated per-session MeerkatMachine DSL authority.
14#[derive(Debug)]
15pub struct RuntimeCommsDrainHandle {
16    dsl: Arc<HandleDslAuthority>,
17}
18
19impl RuntimeCommsDrainHandle {
20    /// Construct a handle backed by the session's shared DSL authority.
21    pub fn new(dsl: Arc<HandleDslAuthority>) -> Self {
22        Self { dsl }
23    }
24
25    /// Construct a handle backed by an ephemeral DSL authority.
26    ///
27    /// See [`RuntimeTurnStateHandle::ephemeral`].
28    pub fn ephemeral() -> Self {
29        Self::new(Arc::new(HandleDslAuthority::ephemeral()))
30    }
31}
32
33impl CommsDrainHandle for RuntimeCommsDrainHandle {
34    fn ensure_drain_running(&self) -> Result<(), DslTransitionError> {
35        self.dsl.apply_signal(
36            mm_dsl::MeerkatMachineSignal::EnsureDrainRunning,
37            "CommsDrainHandle::ensure_drain_running",
38        )
39    }
40
41    fn spawn_drain(&self, mode: DrainMode) -> Result<(), DslTransitionError> {
42        let mode = match mode {
43            DrainMode::Timed => mm_dsl::DrainMode::Timed,
44            DrainMode::AttachedSession => mm_dsl::DrainMode::AttachedSession,
45            DrainMode::PersistentHost => mm_dsl::DrainMode::PersistentHost,
46        };
47        // intra-machine: no route; dispatcher not applicable (handle targets the meerkat DSL directly, not a CompositionDispatcher seam)
48        self.dsl.apply_input(
49            mm_dsl::MeerkatMachineInput::SpawnDrain { mode },
50            "CommsDrainHandle::spawn_drain",
51        )
52    }
53
54    fn stop_drain(&self) -> Result<(), DslTransitionError> {
55        // intra-machine: no route; dispatcher not applicable (handle targets the meerkat DSL directly, not a CompositionDispatcher seam)
56        self.dsl.apply_input(
57            mm_dsl::MeerkatMachineInput::StopDrain,
58            "CommsDrainHandle::stop_drain",
59        )
60    }
61
62    fn drain_exited_clean(&self) -> Result<(), DslTransitionError> {
63        // intra-machine: no route; dispatcher not applicable (handle targets the meerkat DSL directly, not a CompositionDispatcher seam)
64        self.dsl.apply_input(
65            mm_dsl::MeerkatMachineInput::DrainExitedClean,
66            "CommsDrainHandle::drain_exited_clean",
67        )
68    }
69
70    fn drain_exited_respawnable(&self) -> Result<(), DslTransitionError> {
71        // intra-machine: no route; dispatcher not applicable (handle targets the meerkat DSL directly, not a CompositionDispatcher seam)
72        self.dsl.apply_input(
73            mm_dsl::MeerkatMachineInput::DrainExitedRespawnable,
74            "CommsDrainHandle::drain_exited_respawnable",
75        )
76    }
77
78    fn notify_drain_exited(&self, reason: DrainExitReason) -> Result<(), DslTransitionError> {
79        // intra-machine: no route; dispatcher not applicable (handle targets the meerkat DSL directly, not a CompositionDispatcher seam)
80        self.dsl.apply_input(
81            mm_dsl::MeerkatMachineInput::NotifyDrainExited {
82                reason: mm_dsl::DrainExitReason::from(reason),
83            },
84            "CommsDrainHandle::notify_drain_exited",
85        )
86    }
87}