use std::future::Future;
use std::time::Duration;
pub struct ServerHandle {
pub(crate) shutdown: tokio_util::sync::CancellationToken,
pub(crate) done: tokio_util::sync::CancellationToken,
pub(crate) drain_timeout: Duration,
}
impl ServerHandle {
pub fn trigger(&self) {
self.shutdown.cancel();
}
pub async fn join(&self) {
self.done.cancelled().await;
}
pub async fn shutdown(self, _timeout: Duration) {
self.shutdown.cancel();
self.done.cancelled().await;
}
#[inline]
pub fn drain_timeout(&self) -> Duration {
self.drain_timeout
}
}
impl std::fmt::Debug for ServerHandle {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("ServerHandle")
.field("drain_timeout", &self.drain_timeout)
.finish_non_exhaustive()
}
}
pub async fn either<A, B>(a: A, b: B)
where
A: Future<Output = ()>,
B: Future<Output = ()>,
{
use futures_util::future::Either;
let a = std::pin::pin!(a);
let b = std::pin::pin!(b);
match futures_util::future::select(a, b).await {
Either::Left(_) | Either::Right(_) => {}
}
}