1use crate::{
4 signal::Signal,
5 telemetry::metrics::{Metric, Registered},
6 Blob, BufMut, BufferPool, BufferPooler, Clock, Error, Handle, IoBufs, IoBufsMut, Metrics, Name,
7 Spawner, Storage, Supervisor,
8};
9use bytes::{Bytes, BytesMut};
10use commonware_utils::{
11 channel::{fallible::OneshotExt, oneshot},
12 sync::Mutex,
13};
14use governor::clock::{Clock as GovernorClock, ReasonablyRealtime};
15use rand::{TryCryptoRng, TryRng};
16use std::{future::Future, mem, sync::Arc};
17
18const DEFAULT_BUFFER_SIZE: usize = 64 * 1024;
21
22pub struct Channel {
24 buffer: BytesMut,
26
27 waiter: Option<(usize, oneshot::Sender<Bytes>)>,
31
32 buffer_size: usize,
35
36 drain_waiter: Option<oneshot::Sender<()>>,
39
40 sink_alive: bool,
42
43 stream_alive: bool,
45}
46
47impl Channel {
48 pub fn init() -> (Sink, Stream) {
50 Self::init_with_buffer_size(DEFAULT_BUFFER_SIZE)
51 }
52
53 pub fn init_with_buffer_size(buffer_size: usize) -> (Sink, Stream) {
55 let channel = Arc::new(Mutex::new(Self {
56 buffer: BytesMut::new(),
57 waiter: None,
58 buffer_size,
59 drain_waiter: None,
60 sink_alive: true,
61 stream_alive: true,
62 }));
63 (
64 Sink {
65 channel: channel.clone(),
66 state: SinkState::Open,
67 },
68 Stream {
69 channel,
70 buffer: BytesMut::new(),
71 poisoned: false,
72 },
73 )
74 }
75
76 fn restore_front(&mut self, data: Bytes) {
78 if data.is_empty() {
79 return;
80 }
81
82 let mut restored = BytesMut::with_capacity(data.len() + self.buffer.len());
83 restored.extend_from_slice(&data);
84 restored.extend_from_slice(&self.buffer);
85 self.buffer = restored;
86 }
87
88 fn close_sink(&mut self) {
90 self.sink_alive = false;
91
92 self.waiter.take();
94 }
95}
96
97struct RecvWaiterGuard {
98 channel: Arc<Mutex<Channel>>,
99 active: bool,
100}
101
102impl RecvWaiterGuard {
103 const fn new(channel: Arc<Mutex<Channel>>) -> Self {
104 Self {
105 channel,
106 active: true,
107 }
108 }
109
110 const fn disarm(&mut self) {
111 self.active = false;
112 }
113}
114
115impl Drop for RecvWaiterGuard {
116 fn drop(&mut self) {
117 if !self.active {
118 return;
119 }
120
121 self.channel.lock().waiter.take();
122 }
123}
124
125pub struct Sink {
127 channel: Arc<Mutex<Channel>>,
128 state: SinkState,
129}
130
131enum SinkState {
133 Open,
135 Sending,
137 Closed,
139}
140
141impl Sink {
142 fn close(&mut self) {
143 if matches!(self.state, SinkState::Closed) {
144 return;
145 }
146 self.channel.lock().close_sink();
147 self.state = SinkState::Closed;
148 }
149}
150
151impl crate::Sink for Sink {
152 async fn send(&mut self, bufs: impl Into<IoBufs> + Send) -> Result<(), Error> {
153 match self.state {
154 SinkState::Open => {}
155 SinkState::Sending => {
156 self.close();
157 return Err(Error::Closed);
158 }
159 SinkState::Closed => return Err(Error::Closed),
160 }
161
162 let drain_recv = {
163 let mut channel = self.channel.lock();
164
165 if !channel.stream_alive {
167 channel.close_sink();
168 self.state = SinkState::Closed;
169 return Err(Error::SendFailed);
170 }
171
172 channel.buffer.put(bufs.into());
173
174 if channel
177 .waiter
178 .as_ref()
179 .is_some_and(|(requested, _)| *requested <= channel.buffer.len())
180 {
181 let (requested, os_send) = channel.waiter.take().unwrap();
183 let send_amount = channel.buffer.len().min(requested.max(channel.buffer_size));
184 let data = channel.buffer.split_to(send_amount).freeze();
185
186 if let Err(data) = os_send.send(data) {
189 channel.restore_front(data);
190 if !channel.stream_alive {
191 channel.close_sink();
192 self.state = SinkState::Closed;
193 return Err(Error::SendFailed);
194 }
195 }
196 }
197
198 if channel.buffer.len() > channel.buffer_size {
201 assert!(channel.drain_waiter.is_none());
202 let (os_send, os_recv) = oneshot::channel();
203 channel.drain_waiter = Some(os_send);
204 os_recv
205 } else {
206 return Ok(());
207 }
208 };
209
210 self.state = SinkState::Sending;
213
214 match drain_recv.await {
216 Ok(()) => {
217 self.state = SinkState::Open;
218 Ok(())
219 }
220 Err(_) => {
221 self.close();
222 Err(Error::SendFailed)
223 }
224 }
225 }
226}
227
228impl Drop for Sink {
229 fn drop(&mut self) {
230 self.close();
231 }
232}
233
234pub struct Stream {
236 channel: Arc<Mutex<Channel>>,
237 buffer: BytesMut,
239 poisoned: bool,
240}
241
242impl crate::Stream for Stream {
243 async fn recv(&mut self, len: usize) -> Result<IoBufs, Error> {
244 if self.poisoned {
245 return Err(Error::Closed);
246 }
247
248 let os_recv = {
249 let mut channel = self.channel.lock();
250
251 let target = len.max(channel.buffer_size);
253 let pull_amount = channel
254 .buffer
255 .len()
256 .min(target.saturating_sub(self.buffer.len()));
257 if pull_amount > 0 {
258 let data = channel.buffer.split_to(pull_amount);
259 self.buffer.extend_from_slice(&data);
260
261 if channel.buffer.len() <= channel.buffer_size {
263 if let Some(sender) = channel.drain_waiter.take() {
264 sender.send_lossy(());
265 }
266 }
267 }
268
269 if self.buffer.len() >= len {
271 return Ok(IoBufs::from(self.buffer.split_to(len).freeze()));
272 }
273
274 if !channel.sink_alive {
276 self.poisoned = true;
277 return Err(Error::RecvFailed);
278 }
279
280 let remaining = len - self.buffer.len();
282 assert!(channel.waiter.is_none());
283 let (os_send, os_recv) = oneshot::channel();
284 channel.waiter = Some((remaining, os_send));
285 os_recv
286 };
287
288 let mut waiter_guard = RecvWaiterGuard::new(self.channel.clone());
289
290 self.poisoned = true;
292
293 let data = match os_recv.await {
295 Ok(data) => {
296 waiter_guard.disarm();
297 self.poisoned = false;
298 data
299 }
300 Err(_) => {
301 waiter_guard.disarm();
302 return Err(Error::RecvFailed);
303 }
304 };
305 self.buffer.extend_from_slice(&data);
306
307 assert!(self.buffer.len() >= len);
308 Ok(IoBufs::from(self.buffer.split_to(len).freeze()))
309 }
310
311 fn peek(&self, max_len: usize) -> &[u8] {
312 let len = max_len.min(self.buffer.len());
313 &self.buffer[..len]
314 }
315}
316
317impl Drop for Stream {
318 fn drop(&mut self) {
319 let mut channel = self.channel.lock();
320 channel.stream_alive = false;
321
322 channel.drain_waiter.take();
324 }
325}
326
327pub struct DeferredSync {
329 pub release: oneshot::Sender<Result<(), Error>>,
331
332 pub blocked: oneshot::Receiver<()>,
334}
335
336#[derive(Clone, Default)]
344pub struct PendingSyncs {
345 syncs: Arc<Mutex<Vec<DeferredSync>>>,
346 gate: Arc<Mutex<SyncGateState>>,
347}
348
349macro_rules! forward_context {
354 ($wrapper:ident, $field:ident) => {
355 impl<E: Supervisor> Supervisor for $wrapper<E> {
356 fn name(&self) -> Name {
357 self.inner.name()
358 }
359
360 fn child(&self, label: &'static str) -> Self {
361 Self {
362 inner: self.inner.child(label),
363 $field: self.$field.clone(),
364 }
365 }
366
367 fn with_attribute(self, key: &'static str, value: impl std::fmt::Display) -> Self {
368 Self {
369 inner: self.inner.with_attribute(key, value),
370 $field: self.$field,
371 }
372 }
373 }
374
375 impl<E: Clock> Clock for $wrapper<E> {
376 fn current(&self) -> std::time::SystemTime {
377 self.inner.current()
378 }
379
380 fn sleep(
381 &self,
382 duration: std::time::Duration,
383 ) -> impl Future<Output = ()> + Send + 'static {
384 self.inner.sleep(duration)
385 }
386
387 fn sleep_until(
388 &self,
389 deadline: std::time::SystemTime,
390 ) -> impl Future<Output = ()> + Send + 'static {
391 self.inner.sleep_until(deadline)
392 }
393 }
394
395 impl<E: Clock> GovernorClock for $wrapper<E> {
396 type Instant = std::time::SystemTime;
397
398 fn now(&self) -> Self::Instant {
399 self.current()
400 }
401 }
402
403 impl<E: Clock> ReasonablyRealtime for $wrapper<E> {}
404
405 impl<E: Metrics> Metrics for $wrapper<E> {
406 fn register<N: Into<String>, H: Into<String>, M: Metric>(
407 &self,
408 name: N,
409 help: H,
410 metric: M,
411 ) -> Registered<M> {
412 self.inner.register(name, help, metric)
413 }
414
415 fn encode(&self) -> String {
416 self.inner.encode()
417 }
418 }
419
420 impl<E: BufferPooler> BufferPooler for $wrapper<E> {
421 fn network_buffer_pool(&self) -> &BufferPool {
422 self.inner.network_buffer_pool()
423 }
424
425 fn storage_buffer_pool(&self) -> &BufferPool {
426 self.inner.storage_buffer_pool()
427 }
428 }
429
430 impl<E: TryRng> TryRng for $wrapper<E> {
431 type Error = E::Error;
432
433 fn try_next_u32(&mut self) -> Result<u32, Self::Error> {
434 self.inner.try_next_u32()
435 }
436
437 fn try_next_u64(&mut self) -> Result<u64, Self::Error> {
438 self.inner.try_next_u64()
439 }
440
441 fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Self::Error> {
442 self.inner.try_fill_bytes(dest)
443 }
444 }
445
446 impl<E: TryCryptoRng> TryCryptoRng for $wrapper<E> {}
447 };
448}
449
450#[derive(Clone)]
452pub struct DelayedSyncContext<E> {
453 pub inner: E,
454 pub pending: PendingSyncs,
455}
456
457forward_context!(DelayedSyncContext, pending);
458
459impl<E: Spawner> Spawner for DelayedSyncContext<E> {
460 fn shared(mut self, blocking: bool) -> Self {
461 self.inner = self.inner.shared(blocking);
462 self
463 }
464
465 fn dedicated(mut self) -> Self {
466 self.inner = self.inner.dedicated();
467 self
468 }
469
470 fn spawn<F, Fut, T>(self, f: F) -> Handle<T>
471 where
472 F: FnOnce(Self) -> Fut + Send + 'static,
473 Fut: Future<Output = T> + Send + 'static,
474 T: Send + 'static,
475 {
476 let pending = self.pending;
477 self.inner.spawn(move |inner| f(Self { inner, pending }))
478 }
479
480 async fn stop(self, value: i32, timeout: Option<std::time::Duration>) -> Result<(), Error> {
481 self.inner.stop(value, timeout).await
482 }
483
484 fn stopped(&self) -> Signal {
485 self.inner.stopped()
486 }
487}
488
489impl<E: Storage> Storage for DelayedSyncContext<E> {
490 type Blob = DelayedSyncBlob<E::Blob>;
491
492 async fn open_versioned(
493 &self,
494 partition: &str,
495 name: &[u8],
496 versions: std::ops::RangeInclusive<u16>,
497 ) -> Result<(Self::Blob, u64, u16), Error> {
498 let (inner, len, version) = self.inner.open_versioned(partition, name, versions).await?;
499 Ok((
500 DelayedSyncBlob {
501 inner,
502 pending: self.pending.clone(),
503 },
504 len,
505 version,
506 ))
507 }
508
509 async fn remove(&self, partition: &str, name: Option<&[u8]>) -> Result<(), Error> {
510 self.inner.remove(partition, name).await
511 }
512
513 async fn scan(&self, partition: &str) -> Result<Vec<Vec<u8>>, Error> {
514 self.inner.scan(partition).await
515 }
516}
517
518#[derive(Clone)]
520pub struct DelayedSyncBlob<B> {
521 inner: B,
522 pending: PendingSyncs,
523}
524
525impl<B> DelayedSyncBlob<B> {
526 pub fn new(inner: B) -> (Self, PendingSyncs) {
528 let pending = PendingSyncs::default();
529 (
530 Self {
531 inner,
532 pending: pending.clone(),
533 },
534 pending,
535 )
536 }
537}
538
539impl<B: Blob> Blob for DelayedSyncBlob<B> {
540 async fn read_at_buf(
541 &self,
542 offset: u64,
543 len: usize,
544 bufs: impl Into<IoBufsMut> + Send,
545 ) -> Result<IoBufsMut, Error> {
546 self.inner.read_at_buf(offset, len, bufs).await
547 }
548
549 async fn read_at(&self, offset: u64, len: usize) -> Result<IoBufsMut, Error> {
550 self.inner.read_at(offset, len).await
551 }
552
553 async fn write_at(&self, offset: u64, bufs: impl Into<IoBufs> + Send) -> Result<(), Error> {
554 self.inner.write_at(offset, bufs).await
555 }
556
557 async fn write_at_sync(
558 &self,
559 offset: u64,
560 bufs: impl Into<IoBufs> + Send,
561 ) -> Result<(), Error> {
562 if !self.pending.tracking() {
563 return self.inner.write_at_sync(offset, bufs).await;
564 }
565 self.inner.write_at(offset, bufs).await?;
566 self.pending.wait().await?;
567 self.inner.sync().await
568 }
569
570 async fn resize(&self, len: u64) -> Result<(), Error> {
571 self.inner.resize(len).await
572 }
573
574 async fn sync(&self) -> Result<(), Error> {
575 self.pending.wait().await?;
576 self.inner.sync().await
577 }
578
579 async fn start_sync(&self) -> Handle<()> {
580 let inner = self.inner.clone();
581 let waiter = self
582 .pending
583 .observe()
584 .unwrap_or_else(|| self.pending.defer());
585 Handle::from_future(async move {
586 waiter.wait().await?;
587 inner.sync().await
588 })
589 }
590}
591
592pub fn next_pending_sync(pending: &PendingSyncs) -> DeferredSync {
594 let mut pending = pending.lock();
595 assert!(!pending.is_empty(), "no pending sync was started");
596 pending.remove(0)
597}
598
599pub fn release_next_pending_syncs(pending: &PendingSyncs, count: usize) {
601 let syncs = {
602 let mut pending = pending.lock();
603 assert!(
604 pending.len() >= count,
605 "not enough pending syncs: have {}, need {count}",
606 pending.len()
607 );
608 pending.drain(..count).collect::<Vec<_>>()
609 };
610 for sync in syncs {
611 let _ = sync.release.send(Ok(()));
612 }
613}
614
615pub fn release_pending_syncs(pending: &PendingSyncs) {
617 for sync in mem::take(&mut *pending.lock()) {
618 let _ = sync.release.send(Ok(()));
619 }
620}
621
622pub fn fail_pending_syncs(pending: &PendingSyncs) {
624 for sync in mem::take(&mut *pending.lock()) {
625 let err = std::io::Error::other("injected sync failure");
626 let _ = sync.release.send(Err(Error::Io(err.into())));
627 }
628}
629
630struct SyncWaiter {
631 entered: oneshot::Sender<()>,
632 release: oneshot::Receiver<Result<(), Error>>,
633}
634
635impl SyncWaiter {
636 async fn wait(self) -> Result<(), Error> {
637 self.entered.send_lossy(());
638 self.release.await.map_err(|_| Error::Closed)??;
639 Ok(())
640 }
641}
642
643#[derive(Default)]
644struct SyncGateState {
645 tracking: bool,
646 calls: usize,
647 waiter: Option<SyncWaiter>,
648}
649
650impl PendingSyncs {
651 pub fn lock(&self) -> commonware_utils::sync::MutexGuard<'_, Vec<DeferredSync>> {
653 self.syncs.lock()
654 }
655
656 pub fn arm(&self) {
662 let mut state = self.gate.lock();
663 assert!(!state.tracking, "sync gate already armed");
664 assert!(state.waiter.is_none(), "sync gate already has a waiter");
665 state.tracking = true;
666 state.calls = 0;
667 state.waiter = Some(self.defer());
668 }
669
670 pub fn calls(&self) -> usize {
672 self.gate.lock().calls
673 }
674
675 fn tracking(&self) -> bool {
676 self.gate.lock().tracking
677 }
678
679 fn defer(&self) -> SyncWaiter {
680 let (release, release_rx) = oneshot::channel();
681 let (entered, blocked) = oneshot::channel();
682 self.syncs.lock().push(DeferredSync { release, blocked });
683 SyncWaiter {
684 entered,
685 release: release_rx,
686 }
687 }
688
689 fn observe(&self) -> Option<SyncWaiter> {
692 let mut state = self.gate.lock();
693 if !state.tracking {
694 return None;
695 }
696 state.calls += 1;
697 state.waiter.take()
698 }
699
700 async fn wait(&self) -> Result<(), Error> {
701 match self.observe() {
702 Some(waiter) => waiter.wait().await,
703 None => Ok(()),
704 }
705 }
706}
707
708#[derive(Clone)]
710pub struct SyncFaultContext<E> {
711 pub inner: E,
712 pub fail_partition: String,
713}
714
715forward_context!(SyncFaultContext, fail_partition);
716
717impl<E: Storage> Storage for SyncFaultContext<E> {
718 type Blob = SyncFaultBlob<E::Blob>;
719
720 async fn open_versioned(
721 &self,
722 partition: &str,
723 name: &[u8],
724 versions: std::ops::RangeInclusive<u16>,
725 ) -> Result<(Self::Blob, u64, u16), Error> {
726 let (inner, len, version) = self.inner.open_versioned(partition, name, versions).await?;
727 Ok((
728 SyncFaultBlob {
729 inner,
730 faulty: partition == self.fail_partition,
731 },
732 len,
733 version,
734 ))
735 }
736
737 async fn remove(&self, partition: &str, name: Option<&[u8]>) -> Result<(), Error> {
738 self.inner.remove(partition, name).await
739 }
740
741 async fn scan(&self, partition: &str) -> Result<Vec<Vec<u8>>, Error> {
742 self.inner.scan(partition).await
743 }
744}
745
746#[derive(Clone)]
748pub struct SyncFaultBlob<B> {
749 inner: B,
750 faulty: bool,
751}
752
753impl<B: Blob> Blob for SyncFaultBlob<B> {
754 async fn read_at_buf(
755 &self,
756 offset: u64,
757 len: usize,
758 bufs: impl Into<IoBufsMut> + Send,
759 ) -> Result<IoBufsMut, Error> {
760 self.inner.read_at_buf(offset, len, bufs).await
761 }
762
763 async fn read_at(&self, offset: u64, len: usize) -> Result<IoBufsMut, Error> {
764 self.inner.read_at(offset, len).await
765 }
766
767 async fn write_at(&self, offset: u64, bufs: impl Into<IoBufs> + Send) -> Result<(), Error> {
768 self.inner.write_at(offset, bufs).await
769 }
770
771 async fn write_at_sync(
772 &self,
773 offset: u64,
774 bufs: impl Into<IoBufs> + Send,
775 ) -> Result<(), Error> {
776 self.inner.write_at_sync(offset, bufs).await
777 }
778
779 async fn resize(&self, len: u64) -> Result<(), Error> {
780 self.inner.resize(len).await
781 }
782
783 async fn sync(&self) -> Result<(), Error> {
784 if self.faulty {
785 let err = std::io::Error::other("injected partition sync fault");
786 return Err(Error::Io(err.into()));
787 }
788 self.inner.sync().await
789 }
790
791 async fn start_sync(&self) -> Handle<()> {
792 if self.faulty {
793 return Handle::ready(self.sync().await);
794 }
795 self.inner.start_sync().await
796 }
797}
798
799#[cfg(test)]
800mod tests {
801 use super::*;
802 use crate::{deterministic, Clock, Runner, Sink, Spawner, Stream};
803 use commonware_macros::select;
804 use std::{thread::sleep, time::Duration};
805
806 #[test]
807 fn test_send_recv() {
808 let (mut sink, mut stream) = Channel::init();
809 let data = b"hello world";
810
811 let executor = deterministic::Runner::default();
812 executor.start(|_| async move {
813 sink.send(data.as_slice()).await.unwrap();
814 let received = stream.recv(data.len()).await.unwrap();
815 assert_eq!(received.coalesce(), data);
816 });
817 }
818
819 #[test]
820 fn test_send_recv_partial_multiple() {
821 let (mut sink, mut stream) = Channel::init();
822 let data = b"hello";
823 let data2 = b" world";
824
825 let executor = deterministic::Runner::default();
826 executor.start(|_| async move {
827 sink.send(data.as_slice()).await.unwrap();
828 sink.send(data2.as_slice()).await.unwrap();
829 let received = stream.recv(5).await.unwrap();
830 assert_eq!(received.coalesce(), b"hello");
831 let received = stream.recv(5).await.unwrap();
832 assert_eq!(received.coalesce(), b" worl");
833 let received = stream.recv(1).await.unwrap();
834 assert_eq!(received.coalesce(), b"d");
835 });
836 }
837
838 #[test]
839 fn test_send_recv_async() {
840 let (mut sink, mut stream) = Channel::init();
841 let data = b"hello world";
842
843 let executor = deterministic::Runner::default();
844 executor.start(|_| async move {
845 let (received, _) = futures::try_join!(stream.recv(data.len()), async {
846 sleep(Duration::from_millis(50));
847 sink.send(data.as_slice()).await
848 })
849 .unwrap();
850 assert_eq!(received.coalesce(), data);
851 });
852 }
853
854 #[test]
855 fn test_recv_error_sink_dropped_while_waiting() {
856 let (sink, mut stream) = Channel::init();
857
858 let executor = deterministic::Runner::default();
859 executor.start(|context| async move {
860 futures::join!(
861 async {
862 let result = stream.recv(5).await;
863 assert!(matches!(result, Err(Error::RecvFailed)));
864 let result = stream.recv(5).await;
865 assert!(matches!(result, Err(Error::Closed)));
866 },
867 async {
868 context.sleep(Duration::from_millis(50)).await;
870 drop(sink);
871 }
872 );
873 });
874 }
875
876 #[test]
877 fn test_recv_error_sink_dropped_before_recv() {
878 let (sink, mut stream) = Channel::init();
879 drop(sink); let executor = deterministic::Runner::default();
882 executor.start(|_| async move {
883 let result = stream.recv(5).await;
884 assert!(matches!(result, Err(Error::RecvFailed)));
885 let result = stream.recv(5).await;
886 assert!(matches!(result, Err(Error::Closed)));
887 });
888 }
889
890 #[test]
891 fn test_send_error_stream_dropped() {
892 let (mut sink, mut stream) = Channel::init();
893
894 let executor = deterministic::Runner::default();
895 executor.start(|context| async move {
896 assert!(sink.send(b"7 bytes".as_slice()).await.is_ok());
898
899 let handle = context.child("recv").spawn(|_| async move {
901 let _ = stream.recv(5).await;
902 let _ = stream.recv(5).await;
903 });
904
905 context.sleep(Duration::from_millis(50)).await;
907
908 handle.abort();
910 assert!(matches!(handle.await, Err(Error::Closed)));
911
912 let result = sink.send(b"hello world".as_slice()).await;
914 assert!(matches!(result, Err(Error::SendFailed)));
915 let result = sink.send(b"hello world".as_slice()).await;
916 assert!(matches!(result, Err(Error::Closed)));
917 });
918 }
919
920 #[test]
921 fn test_send_error_stream_dropped_before_send() {
922 let (mut sink, stream) = Channel::init();
923 drop(stream); let executor = deterministic::Runner::default();
926 executor.start(|_| async move {
927 let result = sink.send(b"hello world".as_slice()).await;
928 assert!(matches!(result, Err(Error::SendFailed)));
929 let result = sink.send(b"hello world".as_slice()).await;
930 assert!(matches!(result, Err(Error::Closed)));
931 });
932 }
933
934 #[test]
935 fn test_recv_timeout() {
936 let (_sink, mut stream) = Channel::init();
937
938 let executor = deterministic::Runner::default();
941 executor.start(|context| async move {
942 select! {
943 v = stream.recv(5) => {
944 panic!("unexpected value: {v:?}");
945 },
946 _ = context.sleep(Duration::from_millis(100)) => "timeout",
947 };
948 });
949 }
950
951 #[test]
952 fn test_peek_empty() {
953 let (_sink, stream) = Channel::init();
954
955 assert!(stream.peek(10).is_empty());
957 }
958
959 #[test]
960 fn test_peek_after_partial_recv() {
961 let (mut sink, mut stream) = Channel::init();
962
963 let executor = deterministic::Runner::default();
964 executor.start(|_| async move {
965 sink.send(b"hello world".as_slice()).await.unwrap();
967
968 let received = stream.recv(5).await.unwrap();
970 assert_eq!(received.coalesce(), b"hello");
971
972 assert_eq!(stream.peek(100), b" world");
974
975 assert_eq!(stream.peek(3), b" wo");
977
978 assert_eq!(stream.peek(100), b" world");
980
981 let received = stream.recv(6).await.unwrap();
983 assert_eq!(received.coalesce(), b" world");
984
985 assert!(stream.peek(100).is_empty());
987 });
988 }
989
990 #[test]
991 fn test_peek_after_recv_wakeup() {
992 let (mut sink, mut stream) = Channel::init_with_buffer_size(64);
993
994 let executor = deterministic::Runner::default();
995 executor.start(|context| async move {
996 let (tx, rx) = oneshot::channel();
998 let recv_handle = context.child("recv").spawn(|_| async move {
999 let data = stream.recv(3).await.unwrap();
1000 tx.send(stream).ok();
1001 data
1002 });
1003
1004 context.sleep(Duration::from_millis(10)).await;
1006
1007 sink.send(b"ABCDEFGHIJ".as_slice()).await.unwrap();
1009
1010 let received = recv_handle.await.unwrap();
1012 assert_eq!(received.coalesce(), b"ABC");
1013
1014 let stream = rx.await.unwrap();
1016 assert_eq!(stream.peek(100), b"DEFGHIJ");
1017 });
1018 }
1019
1020 #[test]
1021 fn test_peek_multiple_sends() {
1022 let (mut sink, mut stream) = Channel::init();
1023
1024 let executor = deterministic::Runner::default();
1025 executor.start(|_| async move {
1026 sink.send(b"aaa".as_slice()).await.unwrap();
1028 sink.send(b"bbb".as_slice()).await.unwrap();
1029 sink.send(b"ccc".as_slice()).await.unwrap();
1030
1031 let received = stream.recv(4).await.unwrap();
1033 assert_eq!(received.coalesce(), b"aaab");
1034
1035 assert_eq!(stream.peek(100), b"bbccc");
1037 });
1038 }
1039
1040 #[test]
1041 fn test_buffer_size_limit() {
1042 let (mut sink, mut stream) = Channel::init_with_buffer_size(10);
1044
1045 let executor = deterministic::Runner::default();
1046 executor.start(|context| async move {
1047 let send_handle = context.child("sender").spawn(|_| async move {
1050 sink.send(b"0123456789ABCDEF".as_slice()).await.unwrap();
1051 sink
1052 });
1053
1054 let received = stream.recv(2).await.unwrap();
1056 assert_eq!(received.coalesce(), b"01");
1057
1058 assert_eq!(stream.peek(100), b"23456789");
1060
1061 let received = stream.recv(8).await.unwrap();
1064 assert_eq!(received.coalesce(), b"23456789");
1065
1066 let received = stream.recv(2).await.unwrap();
1068 assert_eq!(received.coalesce(), b"AB");
1069
1070 assert_eq!(stream.peek(100), b"CDEF");
1071
1072 send_handle.await.unwrap();
1074 });
1075 }
1076
1077 #[test]
1078 fn test_recv_before_send() {
1079 let (mut sink, mut stream) = Channel::init_with_buffer_size(10);
1081
1082 let executor = deterministic::Runner::default();
1083 executor.start(|context| async move {
1084 let recv_handle = context
1086 .child("recv")
1087 .spawn(|_| async move { stream.recv(3).await.unwrap() });
1088
1089 context.sleep(Duration::from_millis(10)).await;
1091
1092 sink.send(b"ABCDEFGHIJKLMNOP".as_slice()).await.unwrap();
1094
1095 let received = recv_handle.await.unwrap();
1097 assert_eq!(received.coalesce(), b"ABC");
1098 });
1099 }
1100}