use spate_core::pipeline::{ExitReport, StartError};
use std::thread::JoinHandle;
use std::time::{Duration, Instant};
#[derive(Debug)]
pub struct PipelineRun {
rx: crossbeam_channel::Receiver<Result<ExitReport, StartError>>,
join: JoinHandle<()>,
}
impl PipelineRun {
pub fn spawn(run: impl FnOnce() -> Result<ExitReport, StartError> + Send + 'static) -> Self {
let (tx, rx) = crossbeam_channel::bounded(1);
let join = std::thread::spawn(move || {
let _ = tx.send(run());
});
Self { rx, join }
}
pub fn wait_exit(&self, timeout: Duration) -> Option<Result<ExitReport, StartError>> {
self.rx.recv_timeout(timeout).ok()
}
pub fn join(self) -> Result<ExitReport, StartError> {
let report = self.rx.recv().expect("pipeline thread dropped its result");
self.join.join().expect("pipeline thread panicked");
report
}
}
const POLL_INTERVAL: Duration = Duration::from_millis(5);
pub fn wait_until(timeout: Duration, what: &str, mut check: impl FnMut() -> bool) {
let deadline = Instant::now() + timeout;
while Instant::now() < deadline {
if check() {
return;
}
std::thread::sleep(POLL_INTERVAL);
}
panic!("timed out after {timeout:?} waiting for: {what}");
}