use std::future::Future;
use modelpipe::PipeStatus;
use crate::interrupt::Interrupt;
pub(crate) async fn park(
mut status: impl AsyncStatus,
interrupt: &mut Interrupt,
) -> anyhow::Result<()> {
eprintln!("status: {}", status.current().as_str());
loop {
tokio::select! {
r = interrupt.next() => {
r?;
return Ok(());
}
next = status.changed() => {
eprintln!("status: {}", next.as_str());
if next == PipeStatus::Closed {
return Ok(());
}
}
}
}
}
pub(crate) async fn shut_down(handle: impl Future<Output = ()>, interrupt: &mut Interrupt) {
tokio::select! {
() = handle => {}
_ = interrupt.next() => {
eprintln!("interrupted again — cutting rather than waiting");
}
}
}
pub(crate) trait AsyncStatus {
fn current(&self) -> PipeStatus;
fn changed(&mut self) -> impl Future<Output = PipeStatus>;
}
impl AsyncStatus for modelpipe::ServeHandle {
fn current(&self) -> PipeStatus {
self.status()
}
async fn changed(&mut self) -> PipeStatus {
self.status_changed().await
}
}
impl AsyncStatus for modelpipe::ConnectHandle {
fn current(&self) -> PipeStatus {
self.status()
}
async fn changed(&mut self) -> PipeStatus {
self.status_changed().await
}
}
impl<T: AsyncStatus> AsyncStatus for &mut T {
fn current(&self) -> PipeStatus {
(**self).current()
}
async fn changed(&mut self) -> PipeStatus {
(**self).changed().await
}
}