Skip to main content

mai_sdk_core/
bridge.rs

1use std::sync::Arc;
2
3use crate::{
4    handler::Startable,
5    network::{HandlerEvent, NetworkMessage},
6    storage::{GetEvent, SetEvent},
7};
8use anyhow::Result;
9use async_channel::{Receiver, Sender};
10use slog::{error, info, Logger};
11use tokio::select;
12use tokio::sync::RwLock;
13
14type EventBridgeChannel<T> = (Sender<T>, Receiver<T>);
15type EventBridgeSubscribers<T> = Arc<RwLock<Vec<(Sender<T>, Receiver<T>)>>>;
16
17/// EventBridge
18/// Handles routing events of different types between their publishers and subscribers
19#[derive(Clone, Debug)]
20pub struct EventBridge {
21    logger: Logger,
22
23    network_channel: EventBridgeChannel<NetworkMessage>,
24    network_subscribers: EventBridgeSubscribers<NetworkMessage>,
25
26    handler_channel: EventBridgeChannel<HandlerEvent>,
27    handler_subscribers: EventBridgeSubscribers<HandlerEvent>,
28
29    kv_get_channel: EventBridgeChannel<GetEvent>,
30    kv_get_subscribers: EventBridgeSubscribers<GetEvent>,
31
32    kv_set_channel: EventBridgeChannel<SetEvent>,
33    kv_set_subscribers: EventBridgeSubscribers<SetEvent>,
34}
35
36pub enum PublishEvents {
37    NetworkMessage(NetworkMessage),
38    HandlerEvent(HandlerEvent),
39    GetEvent(GetEvent),
40    SetEvent(SetEvent),
41}
42
43impl EventBridge {
44    pub fn new(logger: Logger) -> Self {
45        let (network_tx, network_rx) = async_channel::unbounded();
46        let (handler_tx, handler_rx) = async_channel::unbounded();
47        let (kv_get_tx, kv_get_rx) = async_channel::unbounded();
48        let (kv_set_tx, kv_set_rx) = async_channel::unbounded();
49        Self {
50            logger,
51            network_channel: (network_tx, network_rx),
52            network_subscribers: Arc::new(RwLock::new(vec![])),
53            handler_channel: (handler_tx, handler_rx),
54            handler_subscribers: Arc::new(RwLock::new(vec![])),
55            kv_get_channel: (kv_get_tx, kv_get_rx),
56            kv_get_subscribers: Arc::new(RwLock::new(vec![])),
57            kv_set_channel: (kv_set_tx, kv_set_rx),
58            kv_set_subscribers: Arc::new(RwLock::new(vec![])),
59        }
60    }
61
62    pub async fn publish(&self, event: PublishEvents) -> Result<()> {
63        match event {
64            PublishEvents::NetworkMessage(message) => {
65                if let Err(e) = self.network_channel.0.send(message).await {
66                    return Err(anyhow::anyhow!("Failed to publish message: {:?}", e));
67                };
68                Ok(())
69            }
70            PublishEvents::HandlerEvent(event) => {
71                if let Err(e) = self.handler_channel.0.send(event).await {
72                    return Err(anyhow::anyhow!("Failed to publish event: {:?}", e));
73                };
74                Ok(())
75            }
76            PublishEvents::GetEvent(event) => {
77                if let Err(e) = self.kv_get_channel.0.send(event).await {
78                    return Err(anyhow::anyhow!("Failed to publish get event: {:?}", e));
79                };
80                Ok(())
81            }
82            PublishEvents::SetEvent(event) => {
83                if let Err(e) = self.kv_set_channel.0.send(event).await {
84                    return Err(anyhow::anyhow!("Failed to publish set event: {:?}", e));
85                };
86                Ok(())
87            }
88        }
89    }
90
91    pub async fn subscribe_to_network(&self) -> Receiver<NetworkMessage> {
92        let (tx, rx) = async_channel::unbounded();
93        self.network_subscribers
94            .write()
95            .await
96            .push((tx, rx.clone()));
97        rx
98    }
99
100    pub async fn subscribe_to_handler(&self) -> Receiver<HandlerEvent> {
101        let (tx, rx) = async_channel::unbounded();
102        self.handler_subscribers
103            .write()
104            .await
105            .push((tx, rx.clone()));
106        rx
107    }
108
109    pub async fn subscribe_to_kv_get(&self) -> Receiver<GetEvent> {
110        let (tx, rx) = async_channel::unbounded();
111        self.kv_get_subscribers.write().await.push((tx, rx.clone()));
112        rx
113    }
114
115    pub async fn subscribe_to_kv_set(&self) -> Receiver<SetEvent> {
116        let (tx, rx) = async_channel::unbounded();
117        self.kv_set_subscribers.write().await.push((tx, rx.clone()));
118        rx
119    }
120}
121
122impl Startable for EventBridge {
123    async fn start(&self) -> Result<()> {
124        info!(self.logger, "starting event bridge");
125        loop {
126            select! {
127                network_message = self.network_channel.1.recv() => {
128                    info!(self.logger, "event bridge handling network message");
129                    if let Ok(message) = network_message {
130                        for (tx, _) in self.network_subscribers.read().await.iter() {
131                            if let Err(e) = tx.send(message.clone()).await {
132                                error!(self.logger, "Failed to send message to subscriber: {:?}", e);
133                            }
134                        }
135                    }
136                },
137                handler_event = self.handler_channel.1.recv() => {
138                    info!(self.logger, "event bridge handling handler message");
139                    if let Ok(event) = handler_event {
140                        for (tx, _) in self.handler_subscribers.read().await.iter() {
141                            if let Err(e) = tx.send(event.clone()).await {
142                                error!(self.logger, "Failed to send event to subscriber: {:?}", e);
143                            }
144                        }
145                    }
146                },
147                get_event = self.kv_get_channel.1.recv() => {
148                    info!(self.logger, "event bridge handling get event");
149                    if let Ok(event) = get_event {
150                        for (tx, _) in self.kv_get_subscribers.read().await.iter() {
151                            if let Err(e) = tx.send(event.clone()).await {
152                                error!(self.logger, "Failed to send get event to subscriber: {:?}", e);
153                            }
154                        }
155                    }
156                },
157                set_event = self.kv_set_channel.1.recv() => {
158                    info!(self.logger, "event bridge handling set event");
159                    if let Ok(event) = set_event {
160                        for (tx, _) in self.kv_set_subscribers.read().await.iter() {
161                            if let Err(e) = tx.send(event.clone()).await {
162                                error!(self.logger, "Failed to send set event to subscriber: {:?}", e);
163                            }
164                        }
165                    }
166                },
167            }
168        }
169    }
170}
171
172#[cfg(test)]
173mod tests {
174    use slog::o;
175
176    use super::*;
177
178    #[tokio::test]
179    async fn test_handler_event() -> Result<()> {
180        let event_bridge = EventBridge::new(slog::Logger::root(slog::Discard, o!()));
181        {
182            let event_bridge = event_bridge.clone();
183            tokio::spawn(async move {
184                event_bridge.start().await.unwrap();
185            });
186        }
187
188        let handler_event = HandlerEvent::new(
189            NetworkMessage::new("test".to_string(), vec![]),
190            Some("peer_id".to_string()),
191            Some("topic".to_string()),
192        );
193
194        let first_subscriber = event_bridge.subscribe_to_handler().await;
195        let second_subscriber = event_bridge.subscribe_to_handler().await;
196
197        event_bridge
198            .publish(PublishEvents::HandlerEvent(handler_event.clone()))
199            .await?;
200
201        assert_eq!(first_subscriber.recv().await.unwrap(), handler_event);
202        assert_eq!(second_subscriber.recv().await.unwrap(), handler_event);
203
204        Ok(())
205    }
206}