memlink_runtime/
events.rs1use std::sync::Arc;
6
7#[derive(Debug, Clone)]
9pub enum ModuleEvent {
10 Loading { path: String },
12 Loaded { name: String, duration_ms: u64 },
14 LoadFailed { path: String, error: String },
16 Unloading { name: String },
18 Unloaded { name: String },
20 CallStarted { module: String, method: String },
22 CallCompleted { module: String, method: String, duration_us: u64, success: bool },
24 HealthCheck { module: String, healthy: bool },
26 ConfigChanged { module: String },
28}
29
30pub trait EventListener: Send + Sync {
32 fn on_event(&self, event: &ModuleEvent);
34}
35
36pub struct EventRegistry {
38 listeners: dashmap::DashMap<String, Arc<dyn EventListener>>,
40}
41
42impl EventRegistry {
43 pub fn new() -> Self {
45 Self {
46 listeners: dashmap::DashMap::new(),
47 }
48 }
49
50 pub fn register(&self, id: &str, listener: Arc<dyn EventListener>) {
52 self.listeners.insert(id.to_string(), listener);
53 }
54
55 pub fn unregister(&self, id: &str) -> Option<Arc<dyn EventListener>> {
57 self.listeners.remove(id).map(|(_, v)| v)
58 }
59
60 pub fn emit(&self, event: &ModuleEvent) {
62 for entry in self.listeners.iter() {
63 entry.value().on_event(event);
64 }
65 }
66
67 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
79pub trait CallMiddleware: Send + Sync {
81 fn before_call(&self, module: &str, method: &str, args: &[u8]) -> Result<(), String>;
83
84 fn after_call(&self, module: &str, method: &str, result: &Result<Vec<u8>, String>);
86}
87
88pub struct MiddlewareChain {
90 middleware: Vec<Arc<dyn CallMiddleware>>,
92}
93
94impl MiddlewareChain {
95 pub fn new() -> Self {
97 Self {
98 middleware: Vec::new(),
99 }
100 }
101
102 pub fn add(&mut self, mw: Arc<dyn CallMiddleware>) {
104 self.middleware.push(mw);
105 }
106
107 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 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}