lash_core/plugin/
services.rs1use 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 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}