use anyspawn::{BoxedBlockingTask, BoxedFuture, CustomSpawnerBuilder};
use opentelemetry::Context;
use opentelemetry::context::FutureExt as OtelFutureExt;
#[tokio::main]
async fn main() {
let spawner = CustomSpawnerBuilder::tokio()
.layer(
|task: BoxedFuture| -> BoxedFuture {
let cx = Context::current();
Box::pin(task.with_context(cx))
},
|task: BoxedBlockingTask| -> BoxedBlockingTask {
let cx = Context::current();
Box::new(move || {
let _guard = cx.attach();
task();
})
},
)
.name("tokio_with_otel")
.build();
let parent_cx = Context::current().with_value(RequestId("abc-123".into()));
let _guard = parent_cx.attach();
let result = spawner
.spawn(async {
let cx = Context::current();
let id = cx.get::<RequestId>().map_or("<missing>", |r| r.0.as_str());
println!("spawned task sees RequestId = {id}");
id == "abc-123"
})
.await;
assert!(result, "context should have propagated into the spawned task");
let result = spawner
.spawn_blocking(|| {
let cx = Context::current();
let id = cx.get::<RequestId>().map_or("<missing>", |r| r.0.as_str());
println!("spawned task sees RequestId = {id}");
id == "abc-123"
})
.await;
assert!(result, "context should have propagated into the spawned blocking task");
println!("context propagation works!");
}
#[derive(Debug, Clone)]
struct RequestId(String);