Skip to main content

lash_core/plugin/
services.rs

1use std::sync::Arc;
2
3use super::*;
4
5#[derive(Debug, thiserror::Error)]
6pub enum PluginOperationInvokeError {
7    #[error("unknown plugin operation `{0}`")]
8    Unknown(String),
9    #[error("unknown plugin session `{0}`")]
10    UnknownSession(String),
11    #[error("plugin operation `{0}` requires a session")]
12    MissingSession(String),
13    #[error("plugin operation `{0}` does not accept a session")]
14    UnexpectedSession(String),
15    #[error("plugin operation failed: {0}")]
16    Failed(String),
17    #[error("plugin session registry is unavailable")]
18    SessionRegistryPoisoned,
19}
20
21#[derive(Clone)]
22pub struct RuntimeServices {
23    pub plugins: Arc<PluginSession>,
24    pub attachment_store: Arc<crate::SessionAttachmentStore>,
25    pub process_env_store: Arc<dyn crate::ProcessExecutionEnvStore>,
26    pub clock: Arc<dyn crate::Clock>,
27    pub(crate) store: Option<Arc<dyn crate::store::RuntimePersistence>>,
28    /// Manifest persistence may differ from runtime-state persistence for
29    /// ephemeral process runtimes backed by a parent-bound session factory.
30    pub(crate) attachment_manifest_store: Option<Arc<dyn crate::store::RuntimePersistence>>,
31}
32
33#[derive(Clone)]
34pub struct PersistentRuntimeServices(RuntimeServices);
35
36impl std::ops::Deref for PersistentRuntimeServices {
37    type Target = RuntimeServices;
38
39    fn deref(&self) -> &Self::Target {
40        &self.0
41    }
42}
43
44#[cfg(any(test, feature = "testing"))]
45pub(crate) struct NoopSessionManager;
46
47#[cfg(any(test, feature = "testing"))]
48impl SessionReadService for NoopSessionManager {}
49#[cfg(any(test, feature = "testing"))]
50impl ProcessReadService for NoopSessionManager {}
51#[cfg(any(test, feature = "testing"))]
52impl SessionStateService for NoopSessionManager {}
53#[cfg(any(test, feature = "testing"))]
54impl SessionLifecycleService for NoopSessionManager {}
55#[cfg(any(test, feature = "testing"))]
56impl SessionGraphService for NoopSessionManager {}
57impl RuntimeServices {
58    pub fn new(plugins: Arc<PluginSession>) -> Self {
59        Self {
60            plugins,
61            attachment_store: Arc::new(crate::SessionAttachmentStore::in_memory()),
62            process_env_store: Arc::new(crate::InMemoryProcessExecutionEnvStore::new()),
63            clock: Arc::new(crate::SystemClock),
64            store: None,
65            attachment_manifest_store: None,
66        }
67    }
68
69    pub(crate) fn with_clock(mut self, clock: Arc<dyn crate::Clock>) -> Self {
70        self.clock = clock;
71        self
72    }
73
74    pub(crate) fn with_attachment_store(
75        mut self,
76        attachment_store: Arc<crate::SessionAttachmentStore>,
77    ) -> Self {
78        self.attachment_store = attachment_store;
79        self
80    }
81
82    pub(crate) fn with_process_env_store(
83        mut self,
84        process_env_store: Arc<dyn crate::ProcessExecutionEnvStore>,
85    ) -> Self {
86        self.process_env_store = process_env_store;
87        self
88    }
89}
90
91impl PersistentRuntimeServices {
92    pub fn new(
93        plugins: Arc<PluginSession>,
94        store: Arc<dyn crate::store::RuntimePersistence>,
95    ) -> Self {
96        Self(RuntimeServices {
97            plugins,
98            attachment_store: Arc::new(crate::SessionAttachmentStore::in_memory()),
99            process_env_store: Arc::new(crate::InMemoryProcessExecutionEnvStore::new()),
100            clock: Arc::new(crate::SystemClock),
101            store: Some(Arc::clone(&store)),
102            attachment_manifest_store: Some(store),
103        })
104    }
105
106    pub(crate) fn with_attachment_manifest_store(
107        mut self,
108        store: Arc<dyn crate::store::RuntimePersistence>,
109    ) -> Self {
110        self.0.attachment_manifest_store = Some(store);
111        self
112    }
113
114    pub(crate) fn into_runtime_services(self) -> RuntimeServices {
115        self.0
116    }
117
118    pub fn store(&self) -> Arc<dyn crate::store::RuntimePersistence> {
119        self.0
120            .store
121            .as_ref()
122            .expect("persistent runtime services must carry a store")
123            .clone()
124    }
125}