use std::sync::mpsc::{Receiver, SendError, Sender, channel};
use crate::Argv;
#[derive(Debug)]
pub enum ReplicaApply {
SnapshotBegin,
SnapshotChunk(Vec<u8>),
SnapshotEnd { ack_offset: u64 },
Frame { offset: u64, argv: Argv },
}
#[derive(Clone)]
pub struct ReplicaInboxSender {
inner: Sender<ReplicaApply>,
}
impl ReplicaInboxSender {
pub fn send(&self, ev: ReplicaApply) -> Result<(), SendError<ReplicaApply>> {
self.inner.send(ev)
}
}
pub struct ReplicaInboxReceiver {
pub(crate) inner: Receiver<ReplicaApply>,
}
#[must_use]
pub fn replica_inbox_pair() -> (ReplicaInboxSender, ReplicaInboxReceiver) {
let (tx, rx) = channel();
(
ReplicaInboxSender { inner: tx },
ReplicaInboxReceiver { inner: rx },
)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn pair_round_trips_one_event() {
let (tx, rx) = replica_inbox_pair();
tx.send(ReplicaApply::SnapshotBegin).unwrap();
match rx.inner.recv().unwrap() {
ReplicaApply::SnapshotBegin => {}
other => panic!("expected SnapshotBegin, got {other:?}"),
}
}
#[test]
fn drop_receiver_makes_send_fail() {
let (tx, rx) = replica_inbox_pair();
drop(rx);
let err = tx.send(ReplicaApply::SnapshotBegin).unwrap_err();
match err.0 {
ReplicaApply::SnapshotBegin => {}
other => panic!("expected payload roundtrip, got {other:?}"),
}
}
#[test]
fn sender_is_clone_send_sync() {
fn assert_traits<T: Clone + Send + Sync>() {}
assert_traits::<ReplicaInboxSender>();
}
}