Skip to main content

memlink_runtime/
events.rs

1//! Module events and lifecycle hooks.
2//!
3//! Provides event emission and middleware for module operations.
4
5use std::sync::Arc;
6
7/// Module lifecycle event.
8#[derive(Debug, Clone)]
9pub enum ModuleEvent {
10    /// Module is being loaded.
11    Loading { path: String },
12    /// Module was loaded successfully.
13    Loaded { name: String, duration_ms: u64 },
14    /// Module load failed.
15    LoadFailed { path: String, error: String },
16    /// Module is being unloaded.
17    Unloading { name: String },
18    /// Module was unloaded.
19    Unloaded { name: String },
20    /// Module call started.
21    CallStarted { module: String, method: String },
22    /// Module call completed.
23    CallCompleted { module: String, method: String, duration_us: u64, success: bool },
24    /// Module health check.
25    HealthCheck { module: String, healthy: bool },
26    /// Module configuration changed.
27    ConfigChanged { module: String },
28}
29
30/// Event listener trait.
31pub trait EventListener: Send + Sync {
32    /// Called when an event is emitted.
33    fn on_event(&self, event: &ModuleEvent);
34}
35
36/// Event registry for module events.
37pub struct EventRegistry {
38    /// Registered listeners.
39    listeners: dashmap::DashMap<String, Arc<dyn EventListener>>,
40}
41
42impl EventRegistry {
43    /// Creates a new event registry.
44    pub fn new() -> Self {
45        Self {
46            listeners: dashmap::DashMap::new(),
47        }
48    }
49
50    /// Registers an event listener.
51    pub fn register(&self, id: &str, listener: Arc<dyn EventListener>) {
52        self.listeners.insert(id.to_string(), listener);
53    }
54
55    /// Unregisters an event listener.
56    pub fn unregister(&self, id: &str) -> Option<Arc<dyn EventListener>> {
57        self.listeners.remove(id).map(|(_, v)| v)
58    }
59
60    /// Emits an event to all listeners.
61    pub fn emit(&self, event: &ModuleEvent) {
62        for entry in self.listeners.iter() {
63            entry.value().on_event(event);
64        }
65    }
66
67    /// Returns the number of registered listeners.
68    pub fn listener_count(&self) -> usize {
69        self.listeners.len()
70    }
71}
72
73impl Default for EventRegistry {
74    fn default() -> Self {
75        Self::new()
76    }
77}
78
79/// Middleware for intercepting module calls.
80pub trait CallMiddleware: Send + Sync {
81    /// Called before a module call.
82    fn before_call(&self, module: &str, method: &str, args: &[u8]) -> Result<(), String>;
83
84    /// Called after a module call.
85    fn after_call(&self, module: &str, method: &str, result: &Result<Vec<u8>, String>);
86}
87
88/// Middleware chain for module calls.
89pub struct MiddlewareChain {
90    /// Registered middleware.
91    middleware: Vec<Arc<dyn CallMiddleware>>,
92}
93
94impl MiddlewareChain {
95    /// Creates a new middleware chain.
96    pub fn new() -> Self {
97        Self {
98            middleware: Vec::new(),
99        }
100    }
101
102    /// Adds middleware to the chain.
103    pub fn add(&mut self, mw: Arc<dyn CallMiddleware>) {
104        self.middleware.push(mw);
105    }
106
107    /// Executes before-call hooks.
108    pub fn before_call(&self, module: &str, method: &str, args: &[u8]) -> Result<(), String> {
109        for mw in &self.middleware {
110            mw.before_call(module, method, args)?;
111        }
112        Ok(())
113    }
114
115    /// Executes after-call hooks.
116    pub fn after_call(&self, module: &str, method: &str, result: &Result<Vec<u8>, String>) {
117        for mw in &self.middleware {
118            mw.after_call(module, method, result);
119        }
120    }
121}
122
123impl Default for MiddlewareChain {
124    fn default() -> Self {
125        Self::new()
126    }
127}
128
129#[cfg(test)]
130mod tests {
131    use super::*;
132
133    struct TestListener {
134        events: std::sync::Mutex<Vec<ModuleEvent>>,
135    }
136
137    impl EventListener for TestListener {
138        fn on_event(&self, event: &ModuleEvent) {
139            self.events.lock().unwrap().push(event.clone());
140        }
141    }
142
143    #[test]
144    fn test_event_registry() {
145        let registry = EventRegistry::new();
146        let listener = Arc::new(TestListener {
147            events: std::sync::Mutex::new(Vec::new()),
148        });
149
150        registry.register("test", listener.clone());
151
152        let event = ModuleEvent::Loaded { name: "module".to_string(), duration_ms: 100 };
153        registry.emit(&event);
154
155        let events = listener.events.lock().unwrap();
156        assert_eq!(events.len(), 1);
157    }
158}