use futures_util::{future::BoxFuture, stream::Stream};
use std::{future::Future, time::Duration};
pub trait Runtime: Clone + Send + Sync + 'static {
type Interval: Stream + Send;
type Delay: Future + Send;
fn interval(&self, duration: Duration) -> Self::Interval;
fn spawn(&self, future: BoxFuture<'static, ()>);
fn delay(&self, duration: Duration) -> Self::Delay;
}
#[cfg(feature = "rt-tokio")]
#[cfg_attr(docsrs, doc(cfg(feature = "rt-tokio")))]
#[derive(Debug, Clone)]
pub struct Tokio;
#[cfg(feature = "rt-tokio")]
#[cfg_attr(docsrs, doc(cfg(feature = "rt-tokio")))]
impl Runtime for Tokio {
type Interval = tokio_stream::wrappers::IntervalStream;
type Delay = tokio::time::Sleep;
fn interval(&self, duration: Duration) -> Self::Interval {
crate::util::tokio_interval_stream(duration)
}
fn spawn(&self, future: BoxFuture<'static, ()>) {
let _ = tokio::spawn(future);
}
fn delay(&self, duration: Duration) -> Self::Delay {
tokio::time::sleep(duration)
}
}
#[cfg(feature = "rt-tokio-current-thread")]
#[cfg_attr(docsrs, doc(cfg(feature = "rt-tokio-current-thread")))]
#[derive(Debug, Clone)]
pub struct TokioCurrentThread;
#[cfg(feature = "rt-tokio-current-thread")]
#[cfg_attr(docsrs, doc(cfg(feature = "rt-tokio-current-thread")))]
impl Runtime for TokioCurrentThread {
type Interval = tokio_stream::wrappers::IntervalStream;
type Delay = tokio::time::Sleep;
fn interval(&self, duration: Duration) -> Self::Interval {
crate::util::tokio_interval_stream(duration)
}
fn spawn(&self, future: BoxFuture<'static, ()>) {
std::thread::spawn(move || {
let rt = tokio::runtime::Builder::new_current_thread()
.enable_all()
.build()
.expect("failed to create Tokio current thead runtime for OpenTelemetry batch processing");
rt.block_on(future);
});
}
fn delay(&self, duration: Duration) -> Self::Delay {
tokio::time::sleep(duration)
}
}
#[cfg(feature = "rt-async-std")]
#[cfg_attr(docsrs, doc(cfg(feature = "rt-async-std")))]
#[derive(Debug, Clone)]
pub struct AsyncStd;
#[cfg(feature = "rt-async-std")]
#[cfg_attr(docsrs, doc(cfg(feature = "rt-async-std")))]
impl Runtime for AsyncStd {
type Interval = async_std::stream::Interval;
type Delay = BoxFuture<'static, ()>;
fn interval(&self, duration: Duration) -> Self::Interval {
async_std::stream::interval(duration)
}
fn spawn(&self, future: BoxFuture<'static, ()>) {
let _ = async_std::task::spawn(future);
}
fn delay(&self, duration: Duration) -> Self::Delay {
Box::pin(async_std::task::sleep(duration))
}
}