Skip to main content

rvoip_infra_common/
lib.rs

1/*!
2# infra-common
3
4A common infrastructure layer for the RVOIP stack that provides:
5
6- Event system for inter-component communication
7- Configuration management
8- Component lifecycle management
9- Logging and metrics standardization
10- Common error types and handling
11
12This crate serves as a horizontal layer that all other components in the
13RVOIP stack can leverage to ensure consistency and reduce duplication.
14*/
15
16// Set mimalloc as the global allocator for better memory performance
17// Only when this crate is used as a binary, not as a library dependency
18#[cfg(not(feature = "no-global-allocator"))]
19#[global_allocator]
20static GLOBAL: mimalloc::MiMalloc = mimalloc::MiMalloc;
21
22pub mod config;
23pub mod errors;
24pub mod events;
25pub mod lifecycle;
26pub mod logging;
27#[cfg(feature = "memory-diagnostics")]
28pub mod memory_diagnostics;
29pub mod planes;
30
31pub use config::provider::ConfigProvider;
32pub use errors::types::Error;
33/// Re-export commonly used types
34pub use events::bus::EventBus;
35pub use events::bus::EventBusConfig;
36pub use events::bus::EventPool;
37pub use events::bus::Publisher;
38pub use events::bus::PublisherFactory;
39pub use events::types::EventError;
40pub use events::types::EventPriority;
41pub use events::types::EventResult;
42pub use lifecycle::component::Component;
43pub use logging::setup::setup_logging;
44
45/// Version information
46pub const VERSION: &str = env!("CARGO_PKG_VERSION");
47
48#[cfg(test)]
49mod tests {
50    use super::*;
51    use async_trait::async_trait;
52    use events::types::{Event, EventHandler, EventPriority};
53    use serde::{Deserialize, Serialize};
54    use std::sync::Arc;
55    use std::time::Duration;
56    use tokio::runtime::Runtime;
57
58    #[test]
59    fn it_works() {
60        // Basic test to verify crate builds
61        assert_eq!(2 + 2, 4);
62    }
63
64    #[test]
65    fn test_event_bus_creation() {
66        let bus = events::bus::EventBus::new();
67        assert!(
68            bus.metrics().0 == 0,
69            "New event bus should have 0 published events"
70        );
71    }
72
73    #[test]
74    fn test_event_priorities() {
75        assert!(events::types::EventPriority::Critical > events::types::EventPriority::High);
76        assert!(events::types::EventPriority::High > events::types::EventPriority::Normal);
77        assert!(events::types::EventPriority::Normal > events::types::EventPriority::Low);
78    }
79
80    // Sample event for testing
81    #[derive(Clone, Debug, Serialize, Deserialize)]
82    struct TestEvent {
83        pub id: u64,
84        pub data: String,
85        pub priority: EventPriority,
86    }
87
88    impl Event for TestEvent {
89        fn event_type() -> &'static str {
90            "test_event"
91        }
92
93        fn priority() -> EventPriority {
94            EventPriority::Normal
95        }
96
97        fn as_any(&self) -> &dyn std::any::Any {
98            self
99        }
100    }
101
102    struct TestHandler {
103        counter: Arc<std::sync::atomic::AtomicU64>,
104    }
105
106    #[async_trait]
107    impl EventHandler<TestEvent> for TestHandler {
108        async fn handle(&self, _event: TestEvent) {
109            // Simulate some work
110            tokio::time::sleep(Duration::from_micros(10)).await;
111            self.counter
112                .fetch_add(1, std::sync::atomic::Ordering::Relaxed);
113        }
114    }
115
116    fn create_test_event(id: u64, priority: EventPriority) -> TestEvent {
117        TestEvent {
118            id,
119            data: format!("Event data for event {}", id),
120            priority,
121        }
122    }
123
124    #[test]
125    fn test_event_bus_broadcast() {
126        let rt = Runtime::new().unwrap();
127
128        rt.block_on(async {
129            // Setup
130            let event_bus = events::bus::EventBus::new();
131            let counter = Arc::new(std::sync::atomic::AtomicU64::new(0));
132
133            println!("Registering direct subscriber...");
134            // Register a direct subscriber
135            let handler = TestHandler {
136                counter: counter.clone(),
137            };
138            let _ = event_bus
139                .subscribe::<TestEvent, _>(None, handler)
140                .await
141                .unwrap();
142
143            println!("Creating broadcast channel...");
144            // Also create a channel to receive events via broadcast
145            let mut rx = event_bus.subscribe_broadcast::<TestEvent>().await.unwrap();
146
147            // Spawn a task to count events received through the channel
148            let channel_counter = Arc::new(std::sync::atomic::AtomicU64::new(0));
149            let channel_counter_clone = channel_counter.clone();
150            let channel_task = tokio::spawn(async move {
151                println!("Channel receiver task started");
152                while let Ok(_event) = rx.recv().await {
153                    println!("Received event on channel");
154                    channel_counter_clone.fetch_add(1, std::sync::atomic::Ordering::Relaxed);
155                }
156            });
157
158            // Ensure we have time for all setup to complete
159            tokio::time::sleep(Duration::from_millis(50)).await;
160
161            println!("Publishing event...");
162            // Send an event
163            let result = event_bus
164                .publish(create_test_event(1, EventPriority::Normal))
165                .await;
166            println!("Publish result: {:?}", result);
167
168            // Wait for processing (longer to ensure completion)
169            println!("Waiting for event processing...");
170            tokio::time::sleep(Duration::from_millis(500)).await;
171
172            // Verify the direct subscriber received the event
173            let direct_count = counter.load(std::sync::atomic::Ordering::Relaxed);
174            println!("Direct subscriber count: {}", direct_count);
175            assert_eq!(
176                direct_count, 1,
177                "Direct subscriber should have received the event"
178            );
179
180            // Verify the channel received the event
181            let channel_count = channel_counter.load(std::sync::atomic::Ordering::Relaxed);
182            println!("Channel subscriber count: {}", channel_count);
183            assert_eq!(
184                channel_count, 1,
185                "Broadcast channel should have received the event"
186            );
187
188            // Clean up
189            channel_task.abort();
190        });
191    }
192}