Skip to main content

meerkat_runtime/handles/
session_admission.rs

1//! Runtime impl of [`meerkat_core::handles::SessionAdmissionHandle`].
2
3use std::sync::Arc;
4
5use meerkat_core::comms::InputSource;
6use meerkat_core::handles::{DslTransitionError, SessionAdmissionHandle};
7use meerkat_core::lifecycle::{InputId, RunId};
8
9use super::HandleDslAuthority;
10use crate::meerkat_machine::dsl as mm_dsl;
11
12/// Runtime-backed [`SessionAdmissionHandle`] impl.
13///
14/// Routes every trait method to the corresponding DSL input on a dedicated
15/// per-session MeerkatMachine DSL authority.
16#[derive(Debug)]
17pub struct RuntimeSessionAdmissionHandle {
18    dsl: Arc<HandleDslAuthority>,
19}
20
21impl RuntimeSessionAdmissionHandle {
22    /// Construct a handle backed by the session's shared DSL authority.
23    pub fn new(dsl: Arc<HandleDslAuthority>) -> Self {
24        Self { dsl }
25    }
26
27    /// Construct a handle backed by an ephemeral DSL authority.
28    ///
29    /// See [`RuntimeTurnStateHandle::ephemeral`].
30    pub fn ephemeral() -> Self {
31        Self::new(Arc::new(HandleDslAuthority::ephemeral()))
32    }
33}
34
35impl SessionAdmissionHandle for RuntimeSessionAdmissionHandle {
36    fn ingest(
37        &self,
38        runtime_id: &str,
39        work_id: &str,
40        origin: InputSource,
41    ) -> Result<(), DslTransitionError> {
42        // intra-machine: no route; dispatcher not applicable (handle targets the meerkat DSL directly, not a CompositionDispatcher seam)
43        let state = self.dsl.snapshot_state();
44        self.dsl.apply_input(
45            mm_dsl::MeerkatMachineInput::Ingest {
46                session_id: state.session_id.unwrap_or_default(),
47                runtime_id: mm_dsl::AgentRuntimeId::from(runtime_id.to_string()),
48                fence_token: state.active_fence_token.unwrap_or_default(),
49                generation: state.active_runtime_generation,
50                runtime_epoch_id: state.active_runtime_epoch_id,
51                work_id: mm_dsl::WorkId::from(work_id.to_string()),
52                origin: mm_dsl::WorkOrigin::from(origin),
53            },
54            "SessionAdmissionHandle::ingest",
55        )
56    }
57
58    fn accept_with_completion(
59        &self,
60        input_id: &InputId,
61        request_immediate_processing: bool,
62        interrupt_yielding: bool,
63        wake_if_idle: bool,
64    ) -> Result<(), DslTransitionError> {
65        // intra-machine: no route; dispatcher not applicable (handle targets the meerkat DSL directly, not a CompositionDispatcher seam)
66        self.dsl.apply_input(
67            mm_dsl::MeerkatMachineInput::AcceptWithCompletion {
68                input_id: mm_dsl::InputId::from_domain(input_id),
69                request_immediate_processing,
70                interrupt_yielding,
71                wake_if_idle,
72            },
73            "SessionAdmissionHandle::accept_with_completion",
74        )
75    }
76
77    fn accept_without_wake(&self, input_id: &InputId) -> Result<(), DslTransitionError> {
78        // intra-machine: no route; dispatcher not applicable (handle targets the meerkat DSL directly, not a CompositionDispatcher seam)
79        self.dsl.apply_input(
80            mm_dsl::MeerkatMachineInput::AcceptWithoutWake {
81                input_id: mm_dsl::InputId::from_domain(input_id),
82            },
83            "SessionAdmissionHandle::accept_without_wake",
84        )
85    }
86
87    fn prepare(&self, run_id: &RunId) -> Result<(), DslTransitionError> {
88        // intra-machine: no route; dispatcher not applicable (handle targets the meerkat DSL directly, not a CompositionDispatcher seam)
89        self.dsl.apply_input(
90            mm_dsl::MeerkatMachineInput::Prepare {
91                session_id: mm_dsl::SessionId::default(),
92                run_id: mm_dsl::RunId::from_domain(run_id),
93            },
94            "SessionAdmissionHandle::prepare",
95        )
96    }
97}