use crate::error::Result;
use crate::execution::ExecutionHandle;
use std::sync::OnceLock;
use std::sync::RwLock;
use tokio::task_local;
task_local! {
static TASK_EXECUTION: ExecutionHandle;
}
static EXECUTION_CONTEXT: OnceLock<RwLock<Option<ExecutionHandle>>> = OnceLock::new();
fn get_context() -> &'static RwLock<Option<ExecutionHandle>> {
EXECUTION_CONTEXT.get_or_init(|| RwLock::new(None))
}
pub(crate) fn set_global_execution(execution: ExecutionHandle) -> Result<()> {
let context = get_context();
let mut ctx = context.write().expect("Failed to acquire write lock");
*ctx = Some(execution);
Ok(())
}
pub(crate) fn get_current_execution() -> Option<ExecutionHandle> {
if let Ok(handle) = TASK_EXECUTION.try_with(|h| h.clone()) {
return Some(handle);
}
let context = get_context();
let ctx = context.read().expect("Failed to acquire read lock");
ctx.clone()
}
pub(crate) fn clear_global_execution() {
let context = get_context();
let mut ctx = context.write().expect("Failed to acquire write lock");
*ctx = None;
}
pub async fn with_execution<F, T>(execution: ExecutionHandle, future: F) -> T
where
F: std::future::Future<Output = T>,
{
TASK_EXECUTION.scope(execution, future).await
}