use flowscope::driver::BroadcastSlotHandle;
use flowscope::extract::FiveTupleKey;
pub struct EventStream<M>
where
M: Send + Sync + Clone + 'static,
{
handle: BroadcastSlotHandle<M, FiveTupleKey>,
drain_buf: Vec<flowscope::driver::SlotMessage<M, FiveTupleKey>>,
}
impl<M> EventStream<M>
where
M: Send + Sync + Clone + 'static,
{
pub(crate) fn new(handle: BroadcastSlotHandle<M, FiveTupleKey>) -> Self {
Self {
handle,
drain_buf: Vec::with_capacity(32),
}
}
pub fn try_recv(&mut self) -> Option<M> {
self.drain_buf.clear();
if self.handle.drain_n(&mut self.drain_buf, 1) == 0 {
return None;
}
self.drain_buf.pop().map(|msg| msg.message)
}
pub fn recv_many(&mut self, out: &mut Vec<M>, max: usize) -> usize {
self.drain_buf.clear();
let n = self.handle.drain_n(&mut self.drain_buf, max);
out.reserve(n);
out.extend(self.drain_buf.drain(..).map(|m| m.message));
n
}
pub fn pending(&self) -> usize {
self.handle.pending()
}
pub fn subscribers(&self) -> usize {
self.handle.subscribers()
}
pub fn parser_kind(&self) -> flowscope::ParserKind {
self.handle.parser_kind()
}
}
impl<M> std::fmt::Debug for EventStream<M>
where
M: Send + Sync + Clone + 'static,
{
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("EventStream")
.field("parser_kind", &self.parser_kind())
.field("pending", &self.pending())
.field("subscribers", &self.subscribers())
.finish()
}
}
impl<M> Unpin for EventStream<M> where M: Send + Sync + Clone + 'static {}
impl<M> futures_core::Stream for EventStream<M>
where
M: Send + Sync + Clone + 'static,
{
type Item = M;
fn poll_next(
mut self: std::pin::Pin<&mut Self>,
_cx: &mut std::task::Context<'_>,
) -> std::task::Poll<Option<Self::Item>> {
match self.try_recv() {
Some(msg) => std::task::Poll::Ready(Some(msg)),
None => std::task::Poll::Pending,
}
}
}