1use std::cell::RefCell;
26use std::fmt;
27use std::pin::Pin;
28use std::rc::Rc;
29use std::task::{Context, Poll, Waker};
30
31use futures::Future;
32use futures::future::FusedFuture;
33use gwr_track::connect;
34use gwr_track::entity::{Entity, GetEntity};
35use gwr_track::tracker::aka::Aka;
36
37use crate::engine::Engine;
38use crate::port::monitor::Monitor;
39use crate::sim_error;
40use crate::time::clock::Clock;
41use crate::traits::SimObject;
42use crate::types::{SimError, SimResult};
43
44pub mod monitor;
45
46pub type PortStateResult<T> = Result<Rc<PortState<T>>, SimError>;
47pub type PortGetResult<T> = Result<PortGet<T>, SimError>;
48pub type PortStartGetResult<T> = Result<PortStartGet<T>, SimError>;
49pub type PortPutResult<T> = Result<PortPut<T>, SimError>;
50pub type PortTryPutResult<T> = Result<PortTryPut<T>, SimError>;
51
52pub struct PortState<T>
53where
54 T: SimObject,
55{
56 value: RefCell<Option<T>>,
57 put_released: RefCell<bool>,
58 waiting_get: RefCell<Option<Waker>>,
59 waiting_put: RefCell<Option<Waker>>,
60 pub in_port_entity: Rc<Entity>,
61 monitor: Option<Rc<Monitor>>,
62}
63
64impl<T> PortState<T>
65where
66 T: SimObject,
67{
68 fn new(
69 engine: &Engine,
70 clock: &Clock,
71 in_port_entity: Rc<Entity>,
72 window_size_ticks: Option<u64>,
73 ) -> Self {
74 let monitor = window_size_ticks.map(|window_size_ticks| {
75 Monitor::new_and_register(engine, &in_port_entity, clock, window_size_ticks)
76 });
77 Self {
78 value: RefCell::new(None),
79 put_released: RefCell::new(true),
80 waiting_get: RefCell::new(None),
81 waiting_put: RefCell::new(None),
82 in_port_entity,
83 monitor,
84 }
85 }
86}
87
88pub struct InPort<T>
89where
90 T: SimObject,
91{
92 entity: Rc<Entity>,
93 state: Rc<PortState<T>>,
94 connected: RefCell<bool>,
95}
96
97impl<T> fmt::Display for InPort<T>
98where
99 T: SimObject,
100{
101 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
102 self.entity.fmt(f)
103 }
104}
105
106impl<T> InPort<T>
107where
108 T: SimObject,
109{
110 #[must_use]
111 pub fn new(engine: &Engine, clock: &Clock, parent: &Rc<Entity>, name: &str) -> Self {
112 Self::new_with_renames(engine, clock, parent, name, None)
113 }
114
115 #[must_use]
116 pub fn new_with_renames(
117 engine: &Engine,
118 clock: &Clock,
119 parent: &Rc<Entity>,
120 name: &str,
121 aka: Option<&Aka>,
122 ) -> Self {
123 let entity = Rc::new(Entity::new_with_renames(parent, name, aka));
124 let monitor_window_size = entity.tracker.monitoring_window_size_for(entity.id);
125 Self {
126 entity: entity.clone(),
127 state: Rc::new(PortState::new(engine, clock, entity, monitor_window_size)),
128 connected: RefCell::new(false),
129 }
130 }
131
132 pub fn state(&self) -> PortStateResult<T> {
133 if *self.connected.borrow() {
134 return sim_error!("{self} already connected");
135 }
136
137 *self.connected.borrow_mut() = true;
138 Ok(self.state.clone())
139 }
140
141 #[must_use]
142 pub fn has_value(&self) -> bool {
143 self.state.value.borrow().is_some()
144 }
145
146 #[must_use = "Futures do nothing unless you `.await` or otherwise use them"]
147 pub fn get(&mut self) -> PortGetResult<T> {
148 if !*self.connected.borrow() {
149 return sim_error!("{self} not connected");
150 }
151
152 Ok(PortGet {
153 state: self.state.clone(),
154 done: false,
155 })
156 }
157
158 #[must_use = "Futures do nothing unless you `.await` or otherwise use them"]
160 pub fn start_get(&mut self) -> PortStartGetResult<T> {
161 if !*self.connected.borrow() {
162 return sim_error!("{self} not connected");
163 }
164
165 Ok(PortStartGet {
166 state: self.state.clone(),
167 done: false,
168 })
169 }
170
171 pub fn finish_get(&mut self) {
173 *self.state.put_released.borrow_mut() = true;
174 if let Some(waker) = self.state.waiting_put.borrow_mut().take() {
175 waker.wake();
176 }
177 }
178}
179
180pub struct OutPort<T>
181where
182 T: SimObject,
183{
184 entity: Rc<Entity>,
185 state: Option<Rc<PortState<T>>>,
186}
187
188impl<T> GetEntity for OutPort<T>
189where
190 T: SimObject,
191{
192 fn entity(&self) -> &Rc<Entity> {
193 &self.entity
194 }
195}
196
197impl<T> fmt::Display for OutPort<T>
198where
199 T: SimObject,
200{
201 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
202 self.entity.fmt(f)
203 }
204}
205
206impl<T> OutPort<T>
207where
208 T: SimObject,
209{
210 #[must_use]
211 pub fn new(parent: &Rc<Entity>, name: &str) -> Self {
212 Self::new_with_renames(parent, name, None)
213 }
214
215 #[must_use]
216 pub fn new_with_renames(parent: &Rc<Entity>, name: &str, aka: Option<&Aka>) -> Self {
217 let entity = Rc::new(Entity::new_with_renames(parent, name, aka));
218 Self {
219 entity,
220 state: None,
221 }
222 }
223
224 pub fn connect(&mut self, port_state: PortStateResult<T>) -> SimResult {
225 let port_state = port_state?;
226
227 connect!(self.entity ; port_state.in_port_entity);
228 match self.state {
229 Some(_) => {
230 return sim_error!("{self} already connected");
231 }
232 None => {
233 self.state = Some(port_state);
234 }
235 }
236 Ok(())
237 }
238
239 #[must_use = "Futures do nothing unless you `.await` or otherwise use them"]
240 pub fn put(&mut self, value: T) -> PortPutResult<T> {
241 let state = match self.state.as_ref() {
242 Some(s) => s.clone(),
243 None => return sim_error!("{self} not connected"),
244 };
245 Ok(PortPut {
246 state,
247 value: Some(value),
248 done: false,
249 })
250 }
251
252 #[must_use = "Futures do nothing unless you `.await` or otherwise use them"]
260 pub fn try_put(&mut self) -> PortTryPutResult<T> {
261 let state = match self.state.as_ref() {
262 Some(s) => s.clone(),
263 None => return sim_error!("{self} not connected"),
264 };
265 Ok(PortTryPut { state, done: false })
266 }
267}
268
269pub struct PortPut<T>
270where
271 T: SimObject,
272{
273 state: Rc<PortState<T>>,
274 value: Option<T>,
275 done: bool,
276}
277
278impl<T> Future for PortPut<T>
279where
280 T: SimObject,
281{
282 type Output = ();
283
284 fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
285 match self.value.take() {
286 Some(value) => {
287 assert!(self.state.value.borrow().is_none());
291
292 *self.state.value.borrow_mut() = Some(value);
293 *self.state.put_released.borrow_mut() = false;
294 if let Some(waker) = self.state.waiting_get.borrow_mut().take() {
295 waker.wake();
296 }
297 *self.state.waiting_put.borrow_mut() = Some(cx.waker().clone());
298 Poll::Pending
299 }
300 None => {
301 if *self.state.put_released.borrow() {
302 self.done = true;
304 Poll::Ready(())
305 } else {
306 *self.state.waiting_put.borrow_mut() = Some(cx.waker().clone());
309 Poll::Pending
310 }
311 }
312 }
313 }
314}
315
316impl<T> FusedFuture for PortPut<T>
317where
318 T: SimObject,
319{
320 fn is_terminated(&self) -> bool {
321 self.done
322 }
323}
324
325pub struct PortTryPut<T>
326where
327 T: SimObject,
328{
329 state: Rc<PortState<T>>,
330 done: bool,
331}
332
333impl<T> Future for PortTryPut<T>
334where
335 T: SimObject,
336{
337 type Output = ();
338
339 fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
340 if self.state.waiting_get.borrow().is_some() {
341 self.done = true;
342 Poll::Ready(())
343 } else {
344 *self.state.waiting_put.borrow_mut() = Some(cx.waker().clone());
345 Poll::Pending
346 }
347 }
348}
349
350impl<T> FusedFuture for PortTryPut<T>
351where
352 T: SimObject,
353{
354 fn is_terminated(&self) -> bool {
355 self.done
356 }
357}
358
359pub struct PortGet<T>
360where
361 T: SimObject,
362{
363 state: Rc<PortState<T>>,
364 done: bool,
365}
366
367impl<T> Future for PortGet<T>
368where
369 T: SimObject,
370{
371 type Output = T;
372
373 fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
374 let value = self.state.value.borrow_mut().take();
375 if let Some(value) = value {
376 self.done = true;
377 self.state.waiting_get.borrow_mut().take();
378 *self.state.put_released.borrow_mut() = true;
379
380 if let Some(monitor) = self.state.monitor.as_ref() {
382 monitor.sample(&value);
383 }
384
385 if let Some(waker) = self.state.waiting_put.borrow_mut().take() {
386 waker.wake();
387 }
388 Poll::Ready(value)
389 } else {
390 if let Some(waker) = self.state.waiting_put.borrow_mut().take() {
391 waker.wake();
392 }
393
394 *self.state.waiting_get.borrow_mut() = Some(cx.waker().clone());
395 Poll::Pending
396 }
397 }
398}
399
400impl<T> FusedFuture for PortGet<T>
401where
402 T: SimObject,
403{
404 fn is_terminated(&self) -> bool {
405 self.done
406 }
407}
408
409pub struct PortStartGet<T>
410where
411 T: SimObject,
412{
413 state: Rc<PortState<T>>,
414 done: bool,
415}
416
417impl<T> Future for PortStartGet<T>
418where
419 T: SimObject,
420{
421 type Output = T;
422
423 fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
424 let value = self.state.value.borrow_mut().take();
425 if let Some(value) = value {
426 self.done = true;
427 self.state.waiting_get.borrow_mut().take();
428
429 if let Some(monitor) = self.state.monitor.as_ref() {
431 monitor.sample(&value);
432 }
433
434 Poll::Ready(value)
435 } else {
436 if let Some(waker) = self.state.waiting_put.borrow_mut().take() {
439 waker.wake();
440 }
441 *self.state.waiting_get.borrow_mut() = Some(cx.waker().clone());
442 Poll::Pending
443 }
444 }
445}
446
447impl<T> FusedFuture for PortStartGet<T>
448where
449 T: SimObject,
450{
451 fn is_terminated(&self) -> bool {
452 self.done
453 }
454}
455
456#[cfg(test)]
457mod tests {
458 use std::sync::Arc;
459 use std::sync::atomic::{AtomicUsize, Ordering};
460 use std::task::{Wake, Waker};
461
462 use futures::future::FusedFuture;
463 use futures::task::noop_waker;
464 use gwr_track::Tracker;
465 use gwr_track::entity::Entity;
466 use gwr_track::tracker::dev_null_tracker;
467
468 use super::*;
469 use crate::traits::TotalBytes;
470
471 struct TestContext {
472 _tracker: Tracker,
474 engine: Engine,
475 clock: Clock,
476 }
477
478 fn test_context() -> TestContext {
479 let tracker = dev_null_tracker();
480 let mut engine = Engine::new(&tracker);
481 let clock = engine.default_clock();
482
483 TestContext {
484 _tracker: tracker,
485 engine,
486 clock,
487 }
488 }
489
490 fn test_state<T: SimObject>() -> Rc<PortState<T>> {
491 let context = test_context();
492 let entity = Rc::new(Entity::new(context.engine.top(), "rx"));
493
494 Rc::new(PortState::new(
495 &context.engine,
496 &context.clock,
497 entity,
498 None,
499 ))
500 }
501
502 fn monitored_test_state<T: SimObject>() -> Rc<PortState<T>> {
503 let context = test_context();
504 let entity = Rc::new(Entity::new(context.engine.top(), "rx"));
505
506 Rc::new(PortState::new(
507 &context.engine,
508 &context.clock,
509 entity,
510 Some(1),
511 ))
512 }
513
514 struct WakeCounter {
515 wakes_count: Arc<AtomicUsize>,
516 }
517
518 impl Wake for WakeCounter {
519 fn wake(self: Arc<Self>) {
520 self.wakes_count.fetch_add(1, Ordering::SeqCst);
521 }
522
523 fn wake_by_ref(self: &Arc<Self>) {
524 self.wakes_count.fetch_add(1, Ordering::SeqCst);
525 }
526 }
527
528 fn counting_waker() -> (Arc<AtomicUsize>, Waker) {
529 let wakes_count = Arc::new(AtomicUsize::new(0));
530 let waker = Waker::from(Arc::new(WakeCounter {
531 wakes_count: wakes_count.clone(),
532 }));
533
534 (wakes_count, waker)
535 }
536
537 #[test]
538 fn wake_counter_counts_wake_and_wake_by_ref() {
539 let (wakes_count, waker) = counting_waker();
540
541 waker.wake_by_ref();
542 assert_eq!(wakes_count.load(Ordering::SeqCst), 1);
543
544 waker.wake();
545 assert_eq!(wakes_count.load(Ordering::SeqCst), 2);
546 }
547
548 #[test]
549 fn in_port_state_can_only_connect_once() {
550 let context = test_context();
551 let in_port =
552 InPort::<i32>::new(&context.engine, &context.clock, context.engine.top(), "rx");
553
554 assert!(in_port.state().is_ok());
555
556 let err = in_port
557 .state()
558 .err()
559 .expect("second state call should fail");
560 assert!(format!("{err}").contains("already connected"));
561 }
562
563 #[test]
564 fn out_port_connect_can_only_connect_once() {
565 let context = test_context();
566 let mut out_port = OutPort::<i32>::new(context.engine.top(), "tx");
567 let first_in_port =
568 InPort::new(&context.engine, &context.clock, context.engine.top(), "rx1");
569 let second_in_port =
570 InPort::new(&context.engine, &context.clock, context.engine.top(), "rx2");
571
572 out_port.connect(first_in_port.state()).unwrap();
573
574 let err = out_port.connect(second_in_port.state()).unwrap_err();
575 assert!(format!("{err}").contains("already connected"));
576 }
577
578 #[test]
579 fn out_port_entity_returns_port_entity() {
580 let context = test_context();
581 let out_port = OutPort::<i32>::new(context.engine.top(), "tx");
582
583 assert!(Rc::ptr_eq(out_port.entity(), &out_port.entity));
584 }
585
586 #[test]
587 fn start_get_requires_connection_and_finish_get_wakes_putter() {
588 let context = test_context();
589 let mut in_port =
590 InPort::<i32>::new(&context.engine, &context.clock, context.engine.top(), "rx");
591
592 assert!(in_port.start_get().is_err());
593 assert!(in_port.state().is_ok());
594 assert!(in_port.start_get().is_ok());
595
596 let waker = noop_waker();
597 *in_port.state.waiting_put.borrow_mut() = Some(waker);
598 in_port.finish_get();
599
600 assert!(in_port.state.waiting_put.borrow().is_none());
601 }
602
603 #[test]
604 fn finish_get_without_waiting_putter_is_a_noop() {
605 let context = test_context();
606 let mut in_port =
607 InPort::<i32>::new(&context.engine, &context.clock, context.engine.top(), "rx");
608
609 in_port.finish_get();
610
611 assert!(in_port.state.waiting_put.borrow().is_none());
612 }
613
614 #[test]
615 fn port_put_waits_until_value_is_consumed_before_terminating() {
616 let state = test_state::<i32>();
617 let put = PortPut {
618 state: state.clone(),
619 value: Some(123),
620 done: false,
621 };
622 let mut put = Box::pin(put);
623 let waker = noop_waker();
624 let mut cx = Context::from_waker(&waker);
625
626 assert_eq!(put.as_mut().poll(&mut cx), Poll::Pending);
627 assert!(!put.is_terminated());
628 assert_eq!(*state.value.borrow(), Some(123));
629 assert!(state.waiting_put.borrow().is_some());
630
631 assert_eq!(put.as_mut().poll(&mut cx), Poll::Pending);
632 assert!(!put.is_terminated());
633
634 assert_eq!(state.value.borrow_mut().take(), Some(123));
635 *state.put_released.borrow_mut() = true;
636
637 assert_eq!(put.as_mut().poll(&mut cx), Poll::Ready(()));
638 assert!(put.is_terminated());
639 }
640
641 #[test]
642 fn port_put_waits_for_start_get_to_finish_before_terminating() {
643 let state = test_state::<i32>();
644 let put = PortPut {
645 state: state.clone(),
646 value: Some(123),
647 done: false,
648 };
649 let mut put = Box::pin(put);
650 let start_get = PortStartGet {
651 state: state.clone(),
652 done: false,
653 };
654 let mut start_get = Box::pin(start_get);
655 let waker = noop_waker();
656 let mut cx = Context::from_waker(&waker);
657
658 assert_eq!(put.as_mut().poll(&mut cx), Poll::Pending);
659 assert_eq!(start_get.as_mut().poll(&mut cx), Poll::Ready(123));
660 assert!(state.value.borrow().is_none());
661
662 assert_eq!(put.as_mut().poll(&mut cx), Poll::Pending);
663 assert!(!put.is_terminated());
664
665 *state.put_released.borrow_mut() = true;
666
667 assert_eq!(put.as_mut().poll(&mut cx), Poll::Ready(()));
668 assert!(put.is_terminated());
669 }
670
671 #[test]
672 fn port_try_put_waits_for_getter_then_completes() {
673 let state = test_state::<i32>();
674 let try_put = PortTryPut {
675 state: state.clone(),
676 done: false,
677 };
678 let mut try_put = Box::pin(try_put);
679 let waker = noop_waker();
680 let mut cx = Context::from_waker(&waker);
681
682 assert_eq!(try_put.as_mut().poll(&mut cx), Poll::Pending);
683 assert!(!try_put.is_terminated());
684 assert!(state.waiting_put.borrow().is_some());
685
686 *state.waiting_get.borrow_mut() = Some(noop_waker());
687
688 assert_eq!(try_put.as_mut().poll(&mut cx), Poll::Ready(()));
689 assert!(try_put.is_terminated());
690 }
691
692 #[test]
693 fn connected_out_port_creates_try_put_future() {
694 let context = test_context();
695 let mut out_port = OutPort::<i32>::new(context.engine.top(), "tx");
696 let in_port = InPort::new(&context.engine, &context.clock, context.engine.top(), "rx");
697
698 out_port.connect(in_port.state()).unwrap();
699
700 assert!(out_port.try_put().is_ok());
701 }
702
703 #[test]
704 fn port_get_waits_then_returns_value_and_reports_termination() {
705 let state = test_state::<i32>();
706 let get = PortGet {
707 state: state.clone(),
708 done: false,
709 };
710 let mut get = Box::pin(get);
711 let waker = noop_waker();
712 let mut cx = Context::from_waker(&waker);
713
714 assert_eq!(get.as_mut().poll(&mut cx), Poll::Pending);
715 assert!(!get.is_terminated());
716 assert!(state.waiting_get.borrow().is_some());
717
718 *state.value.borrow_mut() = Some(456);
719 *state.waiting_put.borrow_mut() = Some(noop_waker());
720
721 assert_eq!(get.as_mut().poll(&mut cx), Poll::Ready(456));
722 assert!(get.is_terminated());
723 assert!(state.waiting_put.borrow().is_none());
724 }
725
726 #[test]
727 fn port_get_pending_wakes_waiting_putter() {
728 let state = test_state::<i32>();
729 let get = PortGet {
730 state: state.clone(),
731 done: false,
732 };
733 let mut get = Box::pin(get);
734 let waker = noop_waker();
735 let mut cx = Context::from_waker(&waker);
736 *state.waiting_put.borrow_mut() = Some(noop_waker());
737
738 assert_eq!(get.as_mut().poll(&mut cx), Poll::Pending);
739
740 assert!(state.waiting_put.borrow().is_none());
741 assert!(state.waiting_get.borrow().is_some());
742 }
743
744 #[test]
745 fn port_get_samples_monitored_values() {
746 let state = monitored_test_state::<i32>();
747 let monitor = state
748 .monitor
749 .as_ref()
750 .expect("monitored state should create a monitor");
751 let get = PortGet {
752 state: state.clone(),
753 done: false,
754 };
755 let mut get = Box::pin(get);
756 let waker = noop_waker();
757 let mut cx = Context::from_waker(&waker);
758 *state.value.borrow_mut() = Some(456);
759
760 assert_eq!(get.as_mut().poll(&mut cx), Poll::Ready(456));
761 assert_eq!(monitor.bytes_in_window(), 456_i32.total_bytes());
762 }
763
764 #[test]
765 fn port_start_get_waits_then_returns_value_without_finishing_put() {
766 let state = test_state::<i32>();
767 let start_get = PortStartGet {
768 state: state.clone(),
769 done: false,
770 };
771 let mut start_get = Box::pin(start_get);
772 let waker = noop_waker();
773 let mut cx = Context::from_waker(&waker);
774
775 assert_eq!(start_get.as_mut().poll(&mut cx), Poll::Pending);
776 assert!(!start_get.is_terminated());
777 assert!(state.waiting_get.borrow().is_some());
778
779 let (waiting_put_wakes, waiting_put_waker) = counting_waker();
780 *state.waiting_put.borrow_mut() = Some(waiting_put_waker.clone());
781 *state.value.borrow_mut() = Some(789);
782
783 assert_eq!(start_get.as_mut().poll(&mut cx), Poll::Ready(789));
784 assert!(start_get.is_terminated());
785 assert!(state.waiting_get.borrow().is_none());
786 assert_eq!(waiting_put_wakes.load(Ordering::SeqCst), 0);
787 }
788
789 #[test]
790 fn late_start_get_wakes_try_put_readiness_without_acknowledging_payload() {
791 let state = test_state::<i32>();
792 let (producer_wakes, producer_waker) = counting_waker();
793 let mut producer_cx = Context::from_waker(&producer_waker);
794 let receiver_waker = noop_waker();
795 let mut receiver_cx = Context::from_waker(&receiver_waker);
796 let mut ready = Box::pin(PortTryPut {
797 state: state.clone(),
798 done: false,
799 });
800 assert_eq!(ready.as_mut().poll(&mut producer_cx), Poll::Pending);
801 let mut get = Box::pin(PortStartGet {
802 state: state.clone(),
803 done: false,
804 });
805 assert_eq!(get.as_mut().poll(&mut receiver_cx), Poll::Pending);
806 assert_eq!(
807 producer_wakes.load(Ordering::SeqCst),
808 1,
809 "late getter must publish readiness"
810 );
811 assert_eq!(ready.as_mut().poll(&mut producer_cx), Poll::Ready(()));
812 let mut put = Box::pin(PortPut {
813 state: state.clone(),
814 value: Some(37),
815 done: false,
816 });
817 assert_eq!(put.as_mut().poll(&mut producer_cx), Poll::Pending);
818 assert_eq!(get.as_mut().poll(&mut receiver_cx), Poll::Ready(37));
819 assert!(!*state.put_released.borrow());
820 assert_eq!(
821 put.as_mut().poll(&mut producer_cx),
822 Poll::Pending,
823 "readiness and taking the payload are not its ACK"
824 );
825 *state.put_released.borrow_mut() = true;
826 assert_eq!(put.as_mut().poll(&mut producer_cx), Poll::Ready(()));
827 }
828
829 #[test]
830 fn port_start_get_samples_monitored_values() {
831 let state = monitored_test_state::<i32>();
832 let monitor = state
833 .monitor
834 .as_ref()
835 .expect("monitored state should create a monitor");
836 let start_get = PortStartGet {
837 state: state.clone(),
838 done: false,
839 };
840 let mut start_get = Box::pin(start_get);
841 let waker = noop_waker();
842 let mut cx = Context::from_waker(&waker);
843 *state.value.borrow_mut() = Some(789);
844
845 assert_eq!(start_get.as_mut().poll(&mut cx), Poll::Ready(789));
846 assert_eq!(monitor.bytes_in_window(), 789_i32.total_bytes());
847 }
848}