use std::{
future::Future,
time::{Duration, Instant},
};
use derive_more::{Debug, Display, Error, From};
#[derive(Debug)]
#[debug("Handle {{ .. }}")]
pub struct Handle<T> {
inner: tokio::task::JoinHandle<T>,
}
impl<T> Handle<T> {
pub const fn new(inner: tokio::task::JoinHandle<T>) -> Self {
Self { inner }
}
pub async fn join(self) -> Result<T, JoinError> {
self.inner.await.map_err(JoinError)
}
pub fn abort(&self) {
self.inner.abort();
}
}
#[derive(Debug, Display, Error, From)]
#[display("join error: {_0}")]
pub struct JoinError(pub tokio::task::JoinError);
#[derive(Clone, Debug)]
pub enum Signal {
Open,
Closed(i32),
}
pub trait Spawner: Clone + Send + Sync + 'static {
fn spawn<F, Fut, T>(&self, f: F) -> Handle<T>
where
F: FnOnce(Self) -> Fut + Send + 'static,
Fut: Future<Output = T> + Send + 'static,
T: Send + 'static;
fn with_label(&self, label: &str) -> Self;
fn stop(&self, code: i32, timeout: Option<Duration>) -> impl Future<Output = ()> + Send;
fn stopped(&self) -> impl Future<Output = Signal> + Send;
}
pub trait Clock: Send + Sync + 'static {
fn now(&self) -> Instant;
fn sleep(&self, duration: Duration) -> impl Future<Output = ()> + Send;
}
pub trait Counter: Send + Sync + 'static {
fn inc(&self);
fn inc_by(&self, value: u64);
}
pub trait Histogram: Send + Sync + 'static {
fn record(&self, value: f64);
}
pub trait Gauge: Send + Sync + 'static {
fn set(&self, value: f64);
fn inc(&self);
fn dec(&self);
}
pub trait MetricsRegistry: Send + Sync + 'static {
type Counter: Counter;
type Histogram: Histogram;
type Gauge: Gauge;
fn counter(&self, name: &str, help: &str) -> Self::Counter;
fn histogram(&self, name: &str, help: &str, buckets: &[f64]) -> Self::Histogram;
fn gauge(&self, name: &str, help: &str) -> Self::Gauge;
}