autoagents_core/actor/
transport.rs1use crate::actor::AnyActor;
2use async_trait::async_trait;
3use std::any::Any;
4use std::fmt::Debug;
5use std::sync::Arc;
6
7#[async_trait]
8pub trait Transport: Send + Sync + Debug {
9 async fn send(
10 &self,
11 actor: &dyn AnyActor,
12 msg: Arc<dyn Any + Send + Sync>,
13 ) -> Result<(), Box<dyn std::error::Error + Send + Sync>>;
14}
15
16#[derive(Debug)]
17pub struct LocalTransport;
18
19#[async_trait]
20impl Transport for LocalTransport {
21 async fn send(
22 &self,
23 actor: &dyn AnyActor,
24 msg: Arc<dyn Any + Send + Sync>,
25 ) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
26 actor.send_any(msg).await
27 }
28}
29
30#[cfg(test)]
31mod tests {
32 use super::*;
33 use crate::actor::{ActorMessage, CloneableMessage};
34 use async_trait::async_trait;
35 use std::sync::{Arc, Mutex};
36
37 #[derive(Debug, Clone, PartialEq)]
39 struct TestMessage {
40 content: String,
41 }
42 impl ActorMessage for TestMessage {}
43 impl CloneableMessage for TestMessage {}
44
45 struct MockActor {
47 received_messages: Arc<Mutex<Vec<String>>>,
48 should_fail: bool,
49 }
50
51 impl MockActor {
52 fn new() -> Self {
53 Self {
54 received_messages: Arc::new(Mutex::new(Vec::new())),
55 should_fail: false,
56 }
57 }
58
59 fn with_failure() -> Self {
60 Self {
61 received_messages: Arc::new(Mutex::new(Vec::new())),
62 should_fail: true,
63 }
64 }
65
66 fn received_messages(&self) -> Vec<String> {
67 self.received_messages.lock().unwrap().clone()
68 }
69 }
70
71 impl std::fmt::Debug for MockActor {
72 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
73 f.debug_struct("MockActor")
74 .field("should_fail", &self.should_fail)
75 .finish()
76 }
77 }
78
79 #[async_trait]
80 impl AnyActor for MockActor {
81 async fn send_any(
82 &self,
83 msg: Arc<dyn Any + Send + Sync>,
84 ) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
85 if self.should_fail {
86 return Err("Mock actor failure".into());
87 }
88
89 if let Some(test_msg) = msg.downcast_ref::<TestMessage>() {
90 self.received_messages
91 .lock()
92 .unwrap()
93 .push(test_msg.content.clone());
94 Ok(())
95 } else {
96 Err("Type mismatch in mock actor".into())
97 }
98 }
99 }
100
101 #[tokio::test]
102 async fn test_local_transport_successful_send() {
103 let transport = LocalTransport;
104 let actor = MockActor::new();
105 let msg = TestMessage {
106 content: "test_message".to_string(),
107 };
108 let arc_msg: Arc<dyn Any + Send + Sync> = Arc::new(msg);
109
110 let result = transport.send(&actor, arc_msg).await;
111
112 assert!(result.is_ok());
113 assert_eq!(actor.received_messages(), vec!["test_message"]);
114 }
115
116 #[tokio::test]
117 async fn test_local_transport_failed_send() {
118 let transport = LocalTransport;
119 let actor = MockActor::with_failure();
120 let msg = TestMessage {
121 content: "failing_message".to_string(),
122 };
123 let arc_msg: Arc<dyn Any + Send + Sync> = Arc::new(msg);
124
125 let result = transport.send(&actor, arc_msg).await;
126
127 assert!(result.is_err());
128 assert_eq!(actor.received_messages().len(), 0);
129 }
130
131 #[tokio::test]
132 async fn test_local_transport_multiple_sends() {
133 let transport = LocalTransport;
134 let actor = MockActor::new();
135
136 let msg1 = TestMessage {
137 content: "message_1".to_string(),
138 };
139 let msg2 = TestMessage {
140 content: "message_2".to_string(),
141 };
142 let msg3 = TestMessage {
143 content: "message_3".to_string(),
144 };
145
146 let arc_msg1: Arc<dyn Any + Send + Sync> = Arc::new(msg1);
147 let arc_msg2: Arc<dyn Any + Send + Sync> = Arc::new(msg2);
148 let arc_msg3: Arc<dyn Any + Send + Sync> = Arc::new(msg3);
149
150 let result1 = transport.send(&actor, arc_msg1).await;
151 let result2 = transport.send(&actor, arc_msg2).await;
152 let result3 = transport.send(&actor, arc_msg3).await;
153
154 assert!(result1.is_ok());
155 assert!(result2.is_ok());
156 assert!(result3.is_ok());
157
158 let received = actor.received_messages();
159 assert_eq!(received.len(), 3);
160 assert_eq!(received[0], "message_1");
161 assert_eq!(received[1], "message_2");
162 assert_eq!(received[2], "message_3");
163 }
164
165 #[tokio::test]
166 async fn test_transport_trait_object() {
167 let transport: Box<dyn Transport> = Box::new(LocalTransport);
168 let actor = MockActor::new();
169 let msg = TestMessage {
170 content: "trait_object_test".to_string(),
171 };
172 let arc_msg: Arc<dyn Any + Send + Sync> = Arc::new(msg);
173
174 let result = transport.send(&actor, arc_msg).await;
175
176 assert!(result.is_ok());
177 assert_eq!(actor.received_messages(), vec!["trait_object_test"]);
178 }
179
180 #[tokio::test]
181 async fn test_transport_concurrent_sends() {
182 let transport = Arc::new(LocalTransport);
183 let actor = Arc::new(MockActor::new());
184
185 let handles = (0..10)
186 .map(|i| {
187 let transport = Arc::clone(&transport);
188 let actor = Arc::clone(&actor);
189
190 tokio::spawn(async move {
191 let msg = TestMessage {
192 content: format!("concurrent_message_{i}"),
193 };
194 let arc_msg: Arc<dyn Any + Send + Sync> = Arc::new(msg);
195 transport.send(actor.as_ref(), arc_msg).await
196 })
197 })
198 .collect::<Vec<_>>();
199
200 let results = futures::future::join_all(handles).await;
201
202 for result in results {
204 assert!(result.is_ok());
205 assert!(result.unwrap().is_ok());
206 }
207
208 assert_eq!(actor.received_messages().len(), 10);
210 }
211
212 #[test]
213 fn test_local_transport_creation() {
214 let _transport = LocalTransport;
215 }
217
218 #[test]
219 fn test_local_transport_debug() {
220 let transport = LocalTransport;
221
222 let _debug_str = format!("{transport:?}");
224 }
225
226 #[test]
227 fn test_local_transport_clone() {
228 let transport1 = LocalTransport;
229 let transport2 = LocalTransport;
230
231 let _t1_debug = format!("{transport1:?}");
234 let _t2_debug = format!("{transport2:?}");
235 }
236
237 #[tokio::test]
238 async fn test_transport_with_wrong_message_type() {
239 let transport = LocalTransport;
240 let actor = MockActor::new();
241
242 #[allow(dead_code)]
244 #[derive(Debug)]
245 struct WrongMessage {
246 data: i32,
247 }
248
249 let msg = WrongMessage { data: 42 };
250 let arc_msg: Arc<dyn Any + Send + Sync> = Arc::new(msg);
251
252 let result = transport.send(&actor, arc_msg).await;
253
254 assert!(result.is_err());
256 assert_eq!(actor.received_messages().len(), 0);
257 }
258}