1use async_trait::async_trait;
2use serde_json::Value;
3use std::sync::Arc;
4use std::time::{Duration, Instant};
5use tokio::io::{AsyncBufReadExt, AsyncWriteExt, BufReader};
6use tokio::net::{TcpListener, TcpStream};
7use tokio::sync::{Mutex, RwLock};
8
9#[async_trait]
11pub trait Transport: Send + Sync + 'static {
12 type Connection: Connection;
13
14 async fn listen(&self, addr: &str) -> Result<(), String>;
16
17 async fn accept(&self) -> Result<Self::Connection, String>;
19
20 async fn connect(&self, addr: &str) -> Result<Self::Connection, String>;
22
23 async fn shutdown(&self) -> Result<(), String>;
25}
26
27#[async_trait]
29pub trait Connection: Send + 'static {
30 async fn send(&mut self, msg: Value) -> Result<(), String>;
32
33 async fn recv(&mut self) -> Result<Option<Value>, String>;
35
36 fn id(&self) -> &str;
38
39 async fn close(&mut self) -> Result<(), String>;
41}
42
43#[derive(Debug, Clone)]
45pub struct ConnectionStatus {
46 pub connected: bool,
47 pub reconnect_attempts: u32,
48 pub last_heartbeat: Option<Instant>,
49 pub latency_ms: u64,
50 pub messages_sent: u64,
51 pub messages_received: u64,
52}
53
54pub struct ManagedConnection<T: Transport> {
56 transport: Arc<T>,
57 max_retries: u32,
58 heartbeat_interval: Duration,
59 retry_delay: Duration,
60 status: Arc<RwLock<ConnectionStatus>>,
61 connection: Arc<Mutex<Option<T::Connection>>>,
62}
63
64impl<T: Transport> ManagedConnection<T> {
65 pub fn new(transport: Arc<T>) -> Self {
66 Self {
67 transport,
68 max_retries: 10,
69 heartbeat_interval: Duration::from_secs(30),
70 retry_delay: Duration::from_secs(1),
71 status: Arc::new(RwLock::new(ConnectionStatus {
72 connected: false,
73 reconnect_attempts: 0,
74 last_heartbeat: None,
75 latency_ms: 0,
76 messages_sent: 0,
77 messages_received: 0,
78 })),
79 connection: Arc::new(Mutex::new(None)),
80 }
81 }
82
83 pub async fn connect_with_retry(&self, addr: &str) -> Result<(), String> {
85 for attempt in 1..=self.max_retries {
86 {
87 let mut status = self.status.write().await;
88 status.reconnect_attempts = attempt;
89 }
90
91 match self.transport.connect(addr).await {
92 Ok(conn) => {
93 *self.connection.lock().await = Some(conn);
94 let mut status = self.status.write().await;
95 status.connected = true;
96 status.reconnect_attempts = 0;
97 return Ok(());
98 }
99 Err(e) if attempt < self.max_retries => {
100 eprintln!(
101 "connect failed (attempt {}/{}): {}, retrying...",
102 attempt, self.max_retries, e
103 );
104 tokio::time::sleep(self.retry_delay * attempt).await;
105 }
106 Err(e) => {
107 let mut status = self.status.write().await;
108 status.connected = false;
109 return Err(format!(
110 "connect failed after {} attempts: {}",
111 self.max_retries, e
112 ));
113 }
114 }
115 }
116 unreachable!()
117 }
118
119 pub async fn send(&self, msg: Value) -> Result<(), String> {
121 let mut conn_guard = self.connection.lock().await;
122 let conn = conn_guard
123 .as_mut()
124 .ok_or_else(|| "not connected".to_string())?;
125
126 conn.send(msg).await?;
127
128 let mut status = self.status.write().await;
129 status.messages_sent += 1;
130
131 Ok(())
132 }
133
134 pub async fn recv(&self) -> Result<Option<Value>, String> {
136 let mut conn_guard = self.connection.lock().await;
137 let conn = conn_guard
138 .as_mut()
139 .ok_or_else(|| "not connected".to_string())?;
140
141 let result = conn.recv().await?;
142
143 if result.is_some() {
144 let mut status = self.status.write().await;
145 status.messages_received += 1;
146 } else {
147 let mut status = self.status.write().await;
149 status.connected = false;
150 }
151
152 Ok(result)
153 }
154
155 pub async fn start_heartbeat(&self) -> Result<(), String> {
157 let mut interval = tokio::time::interval(self.heartbeat_interval);
158
159 loop {
160 interval.tick().await;
161
162 let ping = serde_json::json!({
163 "type": "ping",
164 "timestamp": std::time::SystemTime::now()
165 .duration_since(std::time::UNIX_EPOCH)
166 .unwrap()
167 .as_millis()
168 });
169
170 let start = Instant::now();
171 self.send(ping).await?;
172
173 match tokio::time::timeout(Duration::from_secs(5), self.recv()).await {
175 Ok(Ok(Some(msg))) if msg["type"] == "pong" => {
176 let latency = start.elapsed().as_millis() as u64;
177 let mut status = self.status.write().await;
178 status.latency_ms = latency;
179 status.last_heartbeat = Some(Instant::now());
180 }
181 Ok(Ok(None)) => {
182 let mut status = self.status.write().await;
183 status.connected = false;
184 return Err("connection closed during heartbeat".into());
185 }
186 Ok(Err(e)) => {
187 let mut status = self.status.write().await;
188 status.connected = false;
189 return Err(format!("heartbeat error: {}", e));
190 }
191 Err(_) => {
192 let mut status = self.status.write().await;
193 status.connected = false;
194 return Err("heartbeat timeout".into());
195 }
196 _ => {}
197 }
198 }
199 }
200
201 pub async fn status(&self) -> ConnectionStatus {
203 self.status.read().await.clone()
204 }
205
206 pub async fn close(&self) -> Result<(), String> {
208 let mut conn_guard = self.connection.lock().await;
209 if let Some(mut conn) = conn_guard.take() {
210 conn.close().await?;
211 }
212 let mut status = self.status.write().await;
213 status.connected = false;
214 Ok(())
215 }
216}
217
218impl<T: Transport> Clone for ManagedConnection<T> {
219 fn clone(&self) -> Self {
220 Self {
221 transport: Arc::clone(&self.transport),
222 max_retries: self.max_retries,
223 heartbeat_interval: self.heartbeat_interval,
224 retry_delay: self.retry_delay,
225 status: Arc::clone(&self.status),
226 connection: Arc::clone(&self.connection),
227 }
228 }
229}
230
231pub struct TcpTransport {
234 listener: Mutex<Option<TcpListener>>,
235}
236
237impl TcpTransport {
238 pub fn new() -> Self {
239 Self {
240 listener: Mutex::new(None),
241 }
242 }
243}
244
245#[async_trait]
246impl Transport for TcpTransport {
247 type Connection = TcpConnection;
248
249 async fn listen(&self, addr: &str) -> Result<(), String> {
250 let listener = TcpListener::bind(addr)
251 .await
252 .map_err(|e| format!("bind failed: {e}"))?;
253 *self.listener.lock().await = Some(listener);
254 Ok(())
255 }
256
257 async fn accept(&self) -> Result<TcpConnection, String> {
258 let listener = self.listener.lock().await;
259 let listener = listener.as_ref().ok_or("not listening")?;
260
261 let (stream, addr) = listener
262 .accept()
263 .await
264 .map_err(|e| format!("accept failed: {e}"))?;
265
266 Ok(TcpConnection::new(stream, format!("tcp-{addr}")))
267 }
268
269 async fn connect(&self, addr: &str) -> Result<TcpConnection, String> {
270 let stream = TcpStream::connect(addr)
271 .await
272 .map_err(|e| format!("connect failed: {e}"))?;
273
274 Ok(TcpConnection::new(stream, format!("tcp-client-{addr}")))
275 }
276
277 async fn shutdown(&self) -> Result<(), String> {
278 *self.listener.lock().await = None;
279 Ok(())
280 }
281}
282
283pub struct TcpConnection {
284 reader: BufReader<tokio::net::tcp::OwnedReadHalf>,
285 writer: tokio::net::tcp::OwnedWriteHalf,
286 id: String,
287}
288
289impl TcpConnection {
290 pub fn new(stream: TcpStream, id: String) -> Self {
291 let (reader, writer) = stream.into_split();
292 Self {
293 reader: BufReader::new(reader),
294 writer,
295 id,
296 }
297 }
298}
299
300#[async_trait]
301impl Connection for TcpConnection {
302 async fn send(&mut self, msg: Value) -> Result<(), String> {
303 let mut line = serde_json::to_string(&msg).map_err(|e| format!("serialize failed: {e}"))?;
304 line.push('\n');
305
306 self.writer
307 .write_all(line.as_bytes())
308 .await
309 .map_err(|e| format!("write failed: {e}"))?;
310
311 Ok(())
312 }
313
314 async fn recv(&mut self) -> Result<Option<Value>, String> {
315 let mut line = String::new();
316
317 match self.reader.read_line(&mut line).await {
318 Ok(0) => Ok(None), Ok(_) => {
320 let msg =
321 serde_json::from_str(line.trim()).map_err(|e| format!("parse failed: {e}"))?;
322 Ok(Some(msg))
323 }
324 Err(e) => Err(format!("read failed: {e}")),
325 }
326 }
327
328 fn id(&self) -> &str {
329 &self.id
330 }
331
332 async fn close(&mut self) -> Result<(), String> {
333 self.writer
334 .shutdown()
335 .await
336 .map_err(|e| format!("close failed: {e}"))
337 }
338}