monoloop_interpreter/
stream.rs1use monoloop_contracts::{InterpreterError, InterpreterOutputEvent};
4use std::sync::Arc;
5use tokio::sync::{mpsc, Mutex};
6
7#[derive(Debug)]
9pub struct CanonicalEventStream {
10 rx: Mutex<mpsc::Receiver<InterpreterOutputEvent>>,
11}
12
13impl CanonicalEventStream {
14 pub(crate) fn new(rx: mpsc::Receiver<InterpreterOutputEvent>) -> Self {
15 Self { rx: Mutex::new(rx) }
16 }
17
18 pub async fn recv(&self) -> Option<InterpreterOutputEvent> {
21 let mut guard = self.rx.lock().await;
22 guard.recv().await
23 }
24}
25
26#[derive(Clone)]
28pub(crate) struct EventPublisher {
29 tx: mpsc::Sender<InterpreterOutputEvent>,
30 count: Arc<std::sync::atomic::AtomicU64>,
31}
32
33impl EventPublisher {
34 pub(crate) fn new(capacity: usize) -> (Self, CanonicalEventStream) {
35 let (tx, rx) = mpsc::channel(capacity.max(1));
36 (
37 Self {
38 tx,
39 count: Arc::new(std::sync::atomic::AtomicU64::new(0)),
40 },
41 CanonicalEventStream::new(rx),
42 )
43 }
44
45 pub(crate) fn count(&self) -> u64 {
46 self.count.load(std::sync::atomic::Ordering::Relaxed)
47 }
48
49 pub(crate) async fn publish(
51 &self,
52 event: InterpreterOutputEvent,
53 ) -> Result<(), InterpreterError> {
54 self.tx
55 .send(event)
56 .await
57 .map_err(|_| InterpreterError::backpressure())?;
58 self.count
59 .fetch_add(1, std::sync::atomic::Ordering::Relaxed);
60 Ok(())
61 }
62}