use std::time::Duration;
use crate::completion::CompletionEvent;
use crate::error::{Error, Result};
use crate::{BackendFactory, Ring};
#[derive(Clone)]
pub struct BatchDrain<F: BackendFactory> {
ring: Ring<F>,
limit: usize,
}
impl<F: BackendFactory> BatchDrain<F> {
#[must_use]
pub fn new(ring: Ring<F>, limit: usize) -> Self {
Self {
ring,
limit: limit.max(1),
}
}
#[must_use]
pub fn drain(&self, timeout: Option<Duration>) -> Vec<Result<CompletionEvent>> {
let mut completions = Vec::with_capacity(self.limit);
for index in 0..self.limit {
let wait = if index == 0 {
timeout
} else {
Some(Duration::ZERO)
};
match self.ring.complete(wait) {
Ok(event) => completions.push(Ok(event)),
Err(Error::Timeout { .. }) if index > 0 => break,
Err(error) => {
completions.push(Err(error));
break;
}
}
}
completions
}
}