use crate::message::FrameBatch;
use crate::socket::patterns::ready_pipe_queue::PipeMessageSender;
use crate::ZmqError;
use std::collections::VecDeque;
use std::future::Future;
use std::pin::Pin;
use std::task::{Context, Poll};
pub(crate) struct IngressDriver<'a> {
sender_opt: Option<&'a PipeMessageSender>,
ingress_buffer: &'a mut VecDeque<FrameBatch>,
fut: Option<Pin<Box<dyn Future<Output = Result<(), ZmqError>> + Send + 'a>>>,
}
impl<'a> IngressDriver<'a> {
pub fn new(
sender_opt: Option<&'a PipeMessageSender>,
ingress_buffer: &'a mut VecDeque<FrameBatch>,
) -> Self {
Self {
sender_opt,
ingress_buffer,
fut: None,
}
}
}
impl<'a> Future for IngressDriver<'a> {
type Output = Result<usize, ZmqError>;
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
let this = self.get_mut();
let mut total_sent = 0;
if let Some(fut) = this.fut.as_mut() {
match fut.as_mut().poll(cx) {
Poll::Ready(Ok(())) => {
this.fut = None;
let batch = this.ingress_buffer.pop_front().unwrap();
total_sent += batch.len();
}
Poll::Ready(Err(e)) => return Poll::Ready(Err(e)),
Poll::Pending => return Poll::Pending,
}
}
match this.sender_opt {
None => {
for batch in this.ingress_buffer.drain(..) {
total_sent += batch.len();
}
}
Some(sender) => {
total_sent += sender.try_send_batch(this.ingress_buffer);
if let Some(blocked) = this.ingress_buffer.front() {
let fut = sender.send(blocked.clone());
this.fut = Some(Box::pin(fut));
match this.fut.as_mut().unwrap().as_mut().poll(cx) {
Poll::Ready(Ok(())) => {
this.fut = None;
let sent = this.ingress_buffer.pop_front().unwrap();
total_sent += sent.len();
}
Poll::Ready(Err(e)) => return Poll::Ready(Err(e)),
Poll::Pending => {
return if total_sent > 0 {
Poll::Ready(Ok(total_sent))
} else {
Poll::Pending
};
}
}
}
}
}
if total_sent > 0 {
Poll::Ready(Ok(total_sent))
} else {
Poll::Pending
}
}
}