use std::sync::OnceLock;
static RUNTIME: OnceLock<tokio::runtime::Runtime> = OnceLock::new();
pub fn init() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
if RUNTIME.get().is_some() {
return Ok(());
}
let rt = tokio::runtime::Builder::new_multi_thread()
.enable_all()
.build()?;
if RUNTIME.set(rt).is_ok() {
tracing::info!("coordinator tokio runtime initialized");
}
Ok(())
}
pub fn get() -> Option<&'static tokio::runtime::Runtime> {
RUNTIME.get()
}
pub(crate) fn block_on<F>(fut: F) -> Result<F::Output, crate::ContentError>
where
F: std::future::Future,
{
let rt = get().ok_or(crate::ContentError::RuntimeNotInitialized)?;
let start = std::time::Instant::now();
let out = rt.block_on(fut);
tracing::debug!(
elapsed_ms = start.elapsed().as_millis(),
"coordinator tool call completed"
);
Ok(out)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn init_then_get_returns_some() {
init().expect("runtime init should succeed");
assert!(
get().is_some(),
"get() must return the runtime after init()"
);
}
#[test]
fn block_on_runs_on_sidecar() {
init().expect("runtime init should succeed");
let out = block_on(async { 42u8 }).expect("block_on must run on an initialized runtime");
assert_eq!(out, 42);
}
}