use std::future::Future;
use std::sync::OnceLock;
use tokio::runtime::{Handle, Runtime};
static RUNTIME: OnceLock<Runtime> = OnceLock::new();
fn global_runtime() -> &'static Runtime {
RUNTIME.get_or_init(|| {
Runtime::new()
.expect("failed to build global tokio runtime for paimon datafusion integration")
})
}
pub fn runtime() -> Handle {
match Handle::try_current() {
Ok(h) => h,
_ => global_runtime().handle().clone(),
}
}
pub(crate) async fn await_with_runtime<F>(future: F) -> F::Output
where
F: Future,
{
if Handle::try_current().is_ok() {
future.await
} else {
global_runtime().block_on(future)
}
}
pub(crate) fn block_on_with_runtime<F>(future: F, panic_error: &'static str) -> F::Output
where
F: Future + Send + 'static,
F::Output: Send + 'static,
{
if Handle::try_current().is_ok() {
let handle = global_runtime().handle().clone();
std::thread::spawn(move || handle.block_on(future))
.join()
.expect(panic_error)
} else {
global_runtime().block_on(future)
}
}