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<dyn crate::AttachmentStore>,
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}
29
30#[derive(Clone)]
31pub struct PersistentRuntimeServices(RuntimeServices);
32
33impl std::ops::Deref for PersistentRuntimeServices {
34    type Target = RuntimeServices;
35
36    fn deref(&self) -> &Self::Target {
37        &self.0
38    }
39}
40
41#[cfg(any(test, feature = "testing"))]
42pub(crate) struct NoopSessionManager;
43
44#[cfg(any(test, feature = "testing"))]
45impl SessionReadService for NoopSessionManager {}
46#[cfg(any(test, feature = "testing"))]
47impl ProcessReadService for NoopSessionManager {}
48#[cfg(any(test, feature = "testing"))]
49impl SessionStateService for NoopSessionManager {}
50#[cfg(any(test, feature = "testing"))]
51impl SessionLifecycleService for NoopSessionManager {}
52#[cfg(any(test, feature = "testing"))]
53impl SessionGraphService for NoopSessionManager {}
54impl RuntimeServices {
55    pub fn new(plugins: Arc<PluginSession>) -> Self {
56        Self {
57            plugins,
58            attachment_store: Arc::new(crate::InMemoryAttachmentStore::new()),
59            process_env_store: Arc::new(crate::InMemoryProcessExecutionEnvStore::new()),
60            clock: Arc::new(crate::SystemClock),
61            store: None,
62        }
63    }
64
65    pub(crate) fn with_clock(mut self, clock: Arc<dyn crate::Clock>) -> Self {
66        self.clock = clock;
67        self
68    }
69
70    pub(crate) fn with_attachment_store(
71        mut self,
72        attachment_store: Arc<dyn crate::AttachmentStore>,
73    ) -> Self {
74        self.attachment_store = attachment_store;
75        self
76    }
77
78    pub(crate) fn with_process_env_store(
79        mut self,
80        process_env_store: Arc<dyn crate::ProcessExecutionEnvStore>,
81    ) -> Self {
82        self.process_env_store = process_env_store;
83        self
84    }
85}
86
87impl PersistentRuntimeServices {
88    pub fn new(
89        plugins: Arc<PluginSession>,
90        store: Arc<dyn crate::store::RuntimePersistence>,
91    ) -> Self {
92        Self(RuntimeServices {
93            plugins,
94            attachment_store: Arc::new(crate::InMemoryAttachmentStore::new()),
95            process_env_store: Arc::new(crate::InMemoryProcessExecutionEnvStore::new()),
96            clock: Arc::new(crate::SystemClock),
97            store: Some(store),
98        })
99    }
100
101    pub(crate) fn into_runtime_services(self) -> RuntimeServices {
102        self.0
103    }
104
105    pub fn store(&self) -> Arc<dyn crate::store::RuntimePersistence> {
106        self.0
107            .store
108            .as_ref()
109            .expect("persistent runtime services must carry a store")
110            .clone()
111    }
112}