1use std::{path::PathBuf, sync::Arc};
7
8use anyhow::{Context, Result};
9use serde::{Deserialize, Serialize};
10use tokio::sync::RwLock;
11use crate::dev_log;
12
13use crate::{
14 Host::{Activation, ExtensionManager::ExtensionManagerImpl, HostConfig},
15 Transport::Strategy::Transport,
16 WASM::Runtime::{WASMConfig, WASMRuntime},
17};
18
19pub struct ExtensionHostImpl {
21 #[allow(dead_code)]
23 config:HostConfig,
24 transport:Transport,
26 extension_manager:Arc<ExtensionManagerImpl>,
28 activation_engine:Arc<Activation::ActivationEngine>,
30 wasm_runtime:Arc<WASMRuntime>,
32 active_extensions:Arc<RwLock<Vec<String>>>,
34 state:Arc<RwLock<HostState>>,
36}
37
38#[derive(Debug, Clone, PartialEq)]
40pub enum HostState {
41 Created,
43 Ready,
45 Running,
47 ShuttingDown,
49 Terminated,
51}
52
53#[derive(Debug, Clone, Default, Serialize, Deserialize)]
55pub struct HostStats {
56 pub loaded_extensions:usize,
58 pub active_extensions:usize,
60 pub total_activations:u64,
62 pub total_activation_time_ms:u64,
64 pub api_calls:u64,
66 pub errors:u64,
68 pub uptime_seconds:u64,
70}
71
72impl ExtensionHostImpl {
73 pub async fn new(transport:Transport) -> Result<Self> { Self::with_config(transport, HostConfig::default()).await }
91
92 pub async fn with_config(transport:Transport, config:HostConfig) -> Result<Self> {
94 dev_log!("grove", "Creating extension host with config: {:?}", config);
95
96 transport.connect().await.context("Failed to connect transport")?;
98
99 let wasm_config = WASMConfig::new(512, 30000, true);
101 let wasm_runtime = Arc::new(WASMRuntime::new(wasm_config).await?);
102
103 let extension_manager = Arc::new(ExtensionManagerImpl::new(Arc::clone(&wasm_runtime), config.clone()));
105
106 let activation_engine = Arc::new(Activation::ActivationEngine::new(
108 Arc::clone(&extension_manager),
109 config.clone(),
110 ));
111
112 dev_log!("grove", "Extension host created successfully");
113
114 Ok(Self {
115 config,
116 transport,
117 extension_manager,
118 activation_engine,
119 wasm_runtime,
120 active_extensions:Arc::new(RwLock::new(Vec::new())),
121 state:Arc::new(RwLock::new(HostState::Created)),
122 })
123 }
124
125 pub async fn load_extension(&self, path:&PathBuf) -> Result<String> {
127 dev_log!("extensions", "Loading extension from: {:?}", path);
128
129 let extension_id = self
130 .extension_manager
131 .load_extension(path)
132 .await
133 .context("Failed to load extension")?;
134
135 dev_log!("extensions", "Extension loaded: {}", extension_id);
136
137 *self.state.write().await = HostState::Ready;
138
139 Ok(extension_id)
140 }
141
142 pub async fn unload_extension(&self, extension_id:&str) -> Result<()> {
144 dev_log!("extensions", "Unloading extension: {}", extension_id);
145
146 self.extension_manager
147 .unload_extension(extension_id)
148 .await
149 .context("Failed to unload extension")?;
150
151 dev_log!("extensions", "Extension unloaded: {}", extension_id);
152
153 Ok(())
154 }
155
156 pub async fn activate(&self, extension_id:&str) -> Result<()> {
158 dev_log!("extensions", "Activating extension: {}", extension_id);
159
160 let start = std::time::Instant::now();
161
162 let result = self
163 .activation_engine
164 .activate(extension_id)
165 .await
166 .context("Failed to activate extension")?;
167
168 let elapsed = start.elapsed().as_millis() as u64;
169
170 if result.success {
171 dev_log!("extensions", "Extension activated in {}ms: {}", elapsed, extension_id);
172
173 let mut active = self.active_extensions.write().await;
175 if !active.contains(&extension_id.to_string()) {
176 active.push(extension_id.to_string());
177 }
178
179 *self.state.write().await = HostState::Running;
180 } else {
181 dev_log!("extensions", "error: extension activation failed: {}", extension_id);
182 }
183
184 Ok(())
185 }
186
187 pub async fn deactivate(&self, extension_id:&str) -> Result<()> {
189 dev_log!("extensions", "Deactivating extension: {}", extension_id);
190
191 self.activation_engine
192 .deactivate(extension_id)
193 .await
194 .context("Failed to deactivate extension")?;
195
196 let mut active = self.active_extensions.write().await;
198 active.retain(|id| id != extension_id);
199
200 dev_log!("extensions", "Extension deactivated: {}", extension_id);
201
202 Ok(())
203 }
204
205 pub async fn activate_all(&self) -> Result<Vec<String>> {
207 dev_log!("extensions", "Activating all extensions");
208
209 let extensions = self.extension_manager.list_extensions().await;
210 let mut activated = Vec::new();
211 let mut failed = Vec::new();
212
213 for extension_id in extensions {
214 match self.activate(&extension_id).await {
215 Ok(_) => activated.push(extension_id),
216 Err(e) => {
217 dev_log!("extensions", "error: failed to activate {}: {}", extension_id, e);
218 failed.push(extension_id);
219 },
220 }
221 }
222
223 dev_log!("extensions", "warn: activated {} extensions, {} failed", activated.len(), failed.len());
224
225 Ok(activated)
226 }
227
228 pub async fn deactivate_all(&self) -> Result<()> {
230 dev_log!("extensions", "Deactivating all extensions");
231
232 let active = self.active_extensions.read().await.clone();
233
234 for extension_id in active {
235 if let Err(e) = self.deactivate(&extension_id).await {
236 dev_log!("extensions", "error: failed to deactivate {}: {}", extension_id, e);
237 }
238 }
239
240 *self.state.write().await = HostState::Ready;
241
242 Ok(())
243 }
244
245 pub async fn stats(&self) -> HostStats {
247 let active_extensions = self.active_extensions.read().await.len();
248 let loaded_extensions = self.extension_manager.list_extensions().await.len();
249 let extension_stats = self.extension_manager.stats().await;
250
251 HostStats {
252 loaded_extensions,
253 active_extensions,
254 total_activations:extension_stats.total_activated as u64,
255 total_activation_time_ms:extension_stats.total_activation_time_ms,
256 api_calls:0, errors:extension_stats.errors,
258 uptime_seconds:0, }
260 }
261
262 pub async fn state(&self) -> HostState { self.state.read().await.clone() }
264
265 pub fn transport(&self) -> &Transport { &self.transport }
267
268 pub fn extension_manager(&self) -> &Arc<ExtensionManagerImpl> { &self.extension_manager }
270
271 pub fn activation_engine(&self) -> &Arc<Activation::ActivationEngine> { &self.activation_engine }
273
274 pub fn wasm_runtime(&self) -> &Arc<WASMRuntime> { &self.wasm_runtime }
276
277 pub async fn shutdown(&self) -> Result<()> {
279 dev_log!("lifecycle", "Shutting down extension host");
280
281 *self.state.write().await = HostState::ShuttingDown;
282
283 if let Err(e) = self.deactivate_all().await {
285 dev_log!("lifecycle", "error: error deactivating extensions during shutdown: {}", e);
286 }
287
288 if let Err(e) = self.transport.close().await {
290 dev_log!("lifecycle", "error: error closing transport during shutdown: {}", e);
291 }
292
293 if let Err(e) = self.wasm_runtime.shutdown().await {
295 dev_log!("wasm", "error: error shutting down WASM runtime: {}", e);
296 }
297
298 *self.state.write().await = HostState::Terminated;
299
300 dev_log!("lifecycle", "Extension host shutdown complete");
301
302 Ok(())
303 }
304}
305
306impl Drop for ExtensionHostImpl {
307 fn drop(&mut self) {
308 dev_log!("lifecycle", "ExtensionHost dropped");
309 }
310}
311
312#[cfg(test)]
313mod tests {
314 use super::*;
315
316 #[tokio::test]
317 async fn test_host_state() {
318 assert_eq!(HostState::Created, HostState::Created);
319 assert_eq!(HostState::Ready, HostState::Ready);
320 assert_eq!(HostState::Running, HostState::Running);
321 }
322
323 #[test]
324 fn test_host_stats_default() {
325 let stats = HostStats::default();
326 assert_eq!(stats.loaded_extensions, 0);
327 assert_eq!(stats.active_extensions, 0);
328 }
329
330 #[test]
331 fn test_host_config_default() {
332 let config = HostConfig::default();
333 assert_eq!(config.max_extensions, 100);
334 assert_eq!(config.lazy_activation, true);
335 }
336}