use std::{cell::Cell, future::Future, sync::Arc};
use crate::{object::ObjectMeta, trace_id::TraceId};
tokio::task_local! {
static META: Arc<ObjectMeta>;
static TRACE_ID: Cell<TraceId>;
}
pub fn trace_id() -> TraceId {
TRACE_ID.with(Cell::get)
}
pub fn try_trace_id() -> Option<TraceId> {
TRACE_ID.try_with(Cell::get).ok()
}
pub fn set_trace_id(trace_id: TraceId) {
TRACE_ID.with(|stored| stored.set(trace_id));
}
pub fn meta() -> Arc<ObjectMeta> {
META.with(Arc::clone)
}
pub fn try_meta() -> Option<Arc<ObjectMeta>> {
META.try_with(Arc::clone).ok()
}
pub async fn scope<F: Future>(meta: Arc<ObjectMeta>, trace_id: TraceId, f: F) -> F::Output {
META.scope(meta, TRACE_ID.scope(Cell::new(trace_id), f))
.await
}
pub fn sync_scope<R>(meta: Arc<ObjectMeta>, trace_id: TraceId, f: impl FnOnce() -> R) -> R {
META.sync_scope(meta, || TRACE_ID.sync_scope(Cell::new(trace_id), f))
}