1use bytes::Bytes;
2use futures::Stream;
3use parking_lot::Mutex;
4use serde::{Deserialize, Serialize};
5use std::collections::HashMap;
6use std::pin::Pin;
7use std::sync::Arc;
8use std::sync::atomic::{AtomicU64, Ordering};
9use std::task::{Context, Poll};
10use tokio::sync::{Mutex as AsyncMutex, mpsc};
11
12use crate::channel::message::MessageChannel;
13use crate::codec::{BincodeCodec, Codec};
14use crate::error::{Result, RpcError};
15use crate::message::Message;
16use crate::message::types::{MessageId, MessageType};
17
18pub type StreamId = u64;
19
20type StreamSenders = Arc<Mutex<HashMap<StreamId, mpsc::UnboundedSender<Result<Bytes>>>>>;
21
22struct StreamRegistration {
23 stream_id: StreamId,
24 streams: StreamSenders,
25}
26
27impl Drop for StreamRegistration {
28 fn drop(&mut self) {
29 self.streams.lock().remove(&self.stream_id);
30 }
31}
32
33static STREAM_ID_COUNTER: AtomicU64 = AtomicU64::new(1);
34
35pub fn next_stream_id() -> StreamId {
36 STREAM_ID_COUNTER.fetch_add(1, Ordering::Relaxed)
37}
38
39pub struct StreamSender<T: MessageChannel, C: Codec = BincodeCodec> {
40 stream_id: StreamId,
41 sequence: AtomicU64,
42 transport: Arc<T>,
43 codec: C,
44 operation: AsyncMutex<()>,
45 ended: std::sync::atomic::AtomicBool,
46}
47
48impl<T: MessageChannel> StreamSender<T, BincodeCodec> {
49 pub fn new(stream_id: StreamId, transport: Arc<T>) -> Self {
50 Self {
51 stream_id,
52 sequence: AtomicU64::new(0),
53 transport,
54 codec: BincodeCodec,
55 operation: AsyncMutex::new(()),
56 ended: std::sync::atomic::AtomicBool::new(false),
57 }
58 }
59}
60
61impl<T: MessageChannel, C: Codec> StreamSender<T, C> {
62 pub fn with_codec(stream_id: StreamId, transport: Arc<T>, codec: C) -> Self {
63 Self {
64 stream_id,
65 sequence: AtomicU64::new(0),
66 transport,
67 codec,
68 operation: AsyncMutex::new(()),
69 ended: std::sync::atomic::AtomicBool::new(false),
70 }
71 }
72
73 pub async fn send<D: Serialize>(&self, data: D) -> Result<()> {
74 let _operation = self.operation.lock().await;
75 if self.ended.load(Ordering::Acquire) {
76 return Err(RpcError::StreamError("Stream already ended".to_string()));
77 }
78
79 let seq = self.sequence.load(Ordering::Relaxed);
80 let payload = self.codec.encode(&data)?;
81 let chunk = Message::new(
82 MessageId::new(),
83 MessageType::StreamChunk,
84 "",
85 Bytes::from(payload),
86 crate::message::metadata::MessageMetadata::new().with_stream(self.stream_id, seq),
87 );
88 self.transport
89 .send(&chunk)
90 .await
91 .map_err(RpcError::Transport)?;
92 self.sequence.fetch_add(1, Ordering::Relaxed);
93 Ok(())
94 }
95
96 pub async fn end(&self) -> Result<()> {
97 let _operation = self.operation.lock().await;
98 if self.ended.load(Ordering::Acquire) {
99 return Ok(());
100 }
101
102 let end_msg: Message = Message::stream_end(self.stream_id);
103 self.transport
104 .send(&end_msg)
105 .await
106 .map_err(RpcError::Transport)?;
107 self.ended.store(true, Ordering::Release);
108 Ok(())
109 }
110
111 pub fn stream_id(&self) -> StreamId {
112 self.stream_id
113 }
114
115 pub fn is_ended(&self) -> bool {
116 self.ended.load(Ordering::Acquire)
117 }
118}
119
120pub struct StreamReceiver<D, C: Codec = BincodeCodec> {
122 stream_id: StreamId,
123 rx: mpsc::UnboundedReceiver<Result<Bytes>>,
124 ended: bool,
125 codec: C,
126 registration: Option<StreamRegistration>,
127 on_terminate: Option<Box<dyn FnOnce(StreamId) + Send + Sync>>,
128 _phantom: std::marker::PhantomData<D>,
129}
130
131impl<D, C: Codec> StreamReceiver<D, C> {
132 fn finish(&mut self) {
133 self.ended = true;
134 self.registration.take();
135 if let Some(on_terminate) = self.on_terminate.take() {
136 on_terminate(self.stream_id);
137 }
138 }
139
140 pub(crate) fn set_termination_callback(
141 &mut self,
142 callback: impl FnOnce(StreamId) + Send + Sync + 'static,
143 ) {
144 self.on_terminate = Some(Box::new(callback));
145 }
146}
147
148impl<D, C> StreamReceiver<D, C>
149where
150 D: for<'de> Deserialize<'de>,
151 C: Codec,
152{
153 fn new(
154 stream_id: StreamId,
155 rx: mpsc::UnboundedReceiver<Result<Bytes>>,
156 codec: C,
157 registration: StreamRegistration,
158 ) -> Self {
159 Self {
160 stream_id,
161 rx,
162 ended: false,
163 codec,
164 registration: Some(registration),
165 on_terminate: None,
166 _phantom: std::marker::PhantomData,
167 }
168 }
169
170 pub fn stream_id(&self) -> StreamId {
171 self.stream_id
172 }
173
174 pub fn is_ended(&self) -> bool {
175 self.ended
176 }
177
178 pub async fn recv(&mut self) -> Option<Result<D>> {
179 if self.ended {
180 return None;
181 }
182
183 match self.rx.recv().await {
184 Some(Ok(data)) => Some(self.codec.decode(&data)),
185 Some(Err(e)) => {
186 self.finish();
187 Some(Err(e))
188 }
189 None => {
190 self.finish();
191 None
192 }
193 }
194 }
195
196 pub async fn collect(mut self) -> Result<Vec<D>> {
197 let mut items = Vec::new();
198 while let Some(result) = self.recv().await {
199 items.push(result?);
200 }
201 Ok(items)
202 }
203
204 pub fn cancel(&mut self) {
205 self.finish();
206 self.rx.close();
207 }
208}
209
210impl<D, C> Stream for StreamReceiver<D, C>
211where
212 D: for<'de> Deserialize<'de> + Unpin,
213 C: Codec + Unpin,
214{
215 type Item = Result<D>;
216
217 fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
218 if self.ended {
219 return Poll::Ready(None);
220 }
221
222 match self.rx.poll_recv(cx) {
223 Poll::Ready(Some(Ok(data))) => {
224 let result = self.codec.decode(&data);
225 Poll::Ready(Some(result))
226 }
227 Poll::Ready(Some(Err(e))) => {
228 self.finish();
229 Poll::Ready(Some(Err(e)))
230 }
231 Poll::Ready(None) => {
232 self.finish();
233 Poll::Ready(None)
234 }
235 Poll::Pending => Poll::Pending,
236 }
237 }
238}
239
240impl<D, C: Codec> Drop for StreamReceiver<D, C> {
241 fn drop(&mut self) {
242 self.finish();
243 }
244}
245
246pub struct StreamManager<C: Codec = BincodeCodec> {
247 streams: StreamSenders,
248 codec: C,
249}
250
251impl StreamManager<BincodeCodec> {
252 pub fn new() -> Self {
253 Self {
254 streams: Arc::new(Mutex::new(HashMap::new())),
255 codec: BincodeCodec,
256 }
257 }
258}
259
260impl<C: Codec> StreamManager<C> {
261 pub fn with_codec(codec: C) -> Self {
262 Self {
263 streams: Arc::new(Mutex::new(HashMap::new())),
264 codec,
265 }
266 }
267
268 pub fn create_receiver<D>(&self, stream_id: StreamId) -> StreamReceiver<D, C>
269 where
270 D: for<'de> Deserialize<'de>,
271 C: Clone,
272 {
273 let (tx, rx) = mpsc::unbounded_channel();
274 self.streams.lock().insert(stream_id, tx);
275 let registration = StreamRegistration {
276 stream_id,
277 streams: Arc::clone(&self.streams),
278 };
279 StreamReceiver::new(stream_id, rx, self.codec.clone(), registration)
280 }
281
282 pub fn handle_message(&self, message: &Message<C>) -> bool {
283 let stream_id = match message.metadata.stream_id {
284 Some(id) => id,
285 None => return false,
286 };
287
288 let streams = self.streams.lock();
289 let sender = match streams.get(&stream_id) {
290 Some(tx) => tx,
291 None => return false,
292 };
293
294 match message.msg_type {
295 MessageType::StreamChunk => {
296 let _ = sender.send(Ok(message.payload.clone()));
297 true
298 }
299 MessageType::StreamEnd => {
300 drop(streams);
301 self.remove_stream(stream_id);
302 true
303 }
304 _ => false,
305 }
306 }
307
308 pub fn send_error(&self, stream_id: StreamId, error_msg: String) {
310 let sender = self.streams.lock().remove(&stream_id);
311 if let Some(sender) = sender {
312 let _ = sender.send(Err(RpcError::ServerError(error_msg)));
313 }
314 }
315
316 pub fn remove_stream(&self, stream_id: StreamId) {
317 self.streams.lock().remove(&stream_id);
318 }
319
320 pub(crate) fn close_all(&self, error: RpcError) {
321 let streams = {
322 let mut streams = self.streams.lock();
323 std::mem::take(&mut *streams)
324 };
325 for sender in streams.into_values() {
326 let _ = sender.send(Err(error.clone()));
327 }
328 }
329
330 pub fn active_stream_count(&self) -> usize {
331 self.streams.lock().len()
332 }
333}
334
335impl Default for StreamManager<BincodeCodec> {
336 fn default() -> Self {
337 Self::new()
338 }
339}
340
341#[cfg(test)]
342mod tests {
343 use super::*;
344 use crate::channel::message::MessageChannelAdapter;
345 use crate::error::{TransportError, TransportResult};
346 use crate::transport::channel::{ChannelConfig, ChannelFrameTransport};
347 use std::sync::atomic::AtomicUsize;
348
349 #[derive(Debug, Default)]
350 struct SerializedSendChannel {
351 chunk_release: tokio::sync::Notify,
352 chunk_started: tokio::sync::Notify,
353 committed: Mutex<Vec<MessageType>>,
354 }
355
356 #[async_trait::async_trait]
357 impl MessageChannel for SerializedSendChannel {
358 async fn send(&self, message: &Message) -> TransportResult<()> {
359 if message.msg_type == MessageType::StreamChunk {
360 self.chunk_started.notify_one();
361 self.chunk_release.notified().await;
362 }
363 self.committed.lock().push(message.msg_type);
364 Ok(())
365 }
366
367 async fn recv(&self) -> TransportResult<Message> {
368 std::future::pending().await
369 }
370
371 fn is_connected(&self) -> bool {
372 true
373 }
374
375 async fn close(&self) -> TransportResult<()> {
376 Ok(())
377 }
378 }
379
380 #[derive(Debug, Default)]
381 struct RetryEndChannel {
382 attempts: AtomicUsize,
383 first_started: tokio::sync::Notify,
384 }
385
386 #[async_trait::async_trait]
387 impl MessageChannel for RetryEndChannel {
388 async fn send(&self, message: &Message) -> TransportResult<()> {
389 assert_eq!(message.msg_type, MessageType::StreamEnd);
390 match self.attempts.fetch_add(1, Ordering::SeqCst) {
391 0 => {
392 self.first_started.notify_one();
393 std::future::pending().await
394 }
395 1 => Err(TransportError::Timeout {
396 duration_ms: 1,
397 operation: "stream end".to_string(),
398 }),
399 _ => Ok(()),
400 }
401 }
402
403 async fn recv(&self) -> TransportResult<Message> {
404 std::future::pending().await
405 }
406
407 fn is_connected(&self) -> bool {
408 true
409 }
410
411 async fn close(&self) -> TransportResult<()> {
412 Ok(())
413 }
414 }
415
416 #[tokio::test]
417 async fn test_stream_send_and_end_commit_in_serial_order() {
418 let transport = Arc::new(SerializedSendChannel::default());
419 let sender = Arc::new(StreamSender::new(next_stream_id(), Arc::clone(&transport)));
420 let chunk_sender = Arc::clone(&sender);
421 let chunk = tokio::spawn(async move { chunk_sender.send(1).await });
422
423 tokio::time::timeout(
424 std::time::Duration::from_secs(1),
425 transport.chunk_started.notified(),
426 )
427 .await
428 .unwrap();
429 let end_sender = Arc::clone(&sender);
430 let mut end = tokio::spawn(async move { end_sender.end().await });
431 assert!(
432 tokio::time::timeout(std::time::Duration::from_millis(50), &mut end)
433 .await
434 .is_err()
435 );
436
437 transport.chunk_release.notify_one();
438 chunk.await.unwrap().unwrap();
439 end.await.unwrap().unwrap();
440
441 assert_eq!(
442 *transport.committed.lock(),
443 vec![MessageType::StreamChunk, MessageType::StreamEnd]
444 );
445 assert!(matches!(
446 sender.send(2).await,
447 Err(RpcError::StreamError(_))
448 ));
449 }
450
451 #[tokio::test]
452 async fn test_stream_end_can_retry_after_cancellation_and_failure() {
453 let transport = Arc::new(RetryEndChannel::default());
454 let sender = Arc::new(StreamSender::new(next_stream_id(), Arc::clone(&transport)));
455 let first_sender = Arc::clone(&sender);
456 let first = tokio::spawn(async move { first_sender.end().await });
457
458 tokio::time::timeout(
459 std::time::Duration::from_secs(1),
460 transport.first_started.notified(),
461 )
462 .await
463 .unwrap();
464 first.abort();
465 assert!(first.await.unwrap_err().is_cancelled());
466 assert!(!sender.is_ended());
467
468 assert!(matches!(
469 sender.end().await,
470 Err(RpcError::Transport(TransportError::Timeout { .. }))
471 ));
472 assert!(!sender.is_ended());
473
474 sender.end().await.unwrap();
475 assert!(sender.is_ended());
476 sender.end().await.unwrap();
477 assert_eq!(transport.attempts.load(Ordering::SeqCst), 3);
478 }
479
480 #[tokio::test]
481 async fn test_stream_sender_receiver() {
482 let config = ChannelConfig::default();
483 let (t1, t2) = ChannelFrameTransport::create_pair("test", config).unwrap();
484
485 let sender_channel = Arc::new(MessageChannelAdapter::new(t1));
486 let receiver_channel = MessageChannelAdapter::new(t2);
487
488 let stream_id = next_stream_id();
489 let sender = StreamSender::new(stream_id, sender_channel);
490
491 let manager = StreamManager::new();
492 let receiver: StreamReceiver<i32> = manager.create_receiver(stream_id);
493
494 let recv_handle = tokio::spawn(async move {
495 loop {
496 let msg = receiver_channel.recv().await.unwrap();
497 if !manager.handle_message(&msg) {
498 break;
499 }
500 if msg.msg_type == MessageType::StreamEnd {
501 break;
502 }
503 }
504 receiver
505 });
506
507 sender.send(1i32).await.unwrap();
508 sender.send(2i32).await.unwrap();
509 sender.send(3i32).await.unwrap();
510 sender.end().await.unwrap();
511
512 let mut receiver = recv_handle.await.unwrap();
513
514 let items: Vec<i32> = vec![
515 receiver.recv().await.unwrap().unwrap(),
516 receiver.recv().await.unwrap().unwrap(),
517 receiver.recv().await.unwrap().unwrap(),
518 ];
519 assert_eq!(items, vec![1, 2, 3]);
520 assert!(receiver.recv().await.is_none());
521 }
522
523 #[tokio::test]
524 async fn test_stream_end_is_normal_completion() {
525 let manager = StreamManager::new();
526 let stream_id = next_stream_id();
527 let mut receiver: StreamReceiver<i32> = manager.create_receiver(stream_id);
528 let end: Message = Message::stream_end(stream_id);
529
530 assert!(manager.handle_message(&end));
531 assert!(receiver.recv().await.is_none());
532 assert_eq!(manager.active_stream_count(), 0);
533 }
534
535 #[tokio::test]
536 async fn test_close_all_reports_connection_closed() {
537 let manager = StreamManager::new();
538 let mut first: StreamReceiver<i32> = manager.create_receiver(next_stream_id());
539 let mut second: StreamReceiver<i32> = manager.create_receiver(next_stream_id());
540
541 manager.close_all(RpcError::ConnectionClosed);
542
543 assert!(matches!(
544 first.recv().await,
545 Some(Err(RpcError::ConnectionClosed))
546 ));
547 assert!(matches!(
548 second.recv().await,
549 Some(Err(RpcError::ConnectionClosed))
550 ));
551 assert_eq!(manager.active_stream_count(), 0);
552 }
553
554 #[test]
555 fn test_dropped_receiver_removes_stream_registration() {
556 let manager = StreamManager::new();
557 let receiver: StreamReceiver<i32> = manager.create_receiver(next_stream_id());
558
559 assert_eq!(manager.active_stream_count(), 1);
560 drop(receiver);
561 assert_eq!(manager.active_stream_count(), 0);
562 }
563
564 #[tokio::test]
565 async fn test_close_all_preserves_supplied_error() {
566 let manager = StreamManager::new();
567 let mut receiver: StreamReceiver<i32> = manager.create_receiver(next_stream_id());
568
569 manager.close_all(RpcError::Transport(crate::error::TransportError::Protocol(
570 "invalid frame".to_string(),
571 )));
572
573 assert!(matches!(
574 receiver.recv().await,
575 Some(Err(RpcError::Transport(crate::error::TransportError::Protocol(error))))
576 if error == "invalid frame"
577 ));
578 }
579
580 #[test]
581 fn test_stream_id_generation() {
582 let id1 = next_stream_id();
583 let id2 = next_stream_id();
584 assert_ne!(id1, id2);
585 }
586}