request_id, user_id, trace/span context) are still available inside event handlers later in the async call chain.
This is commonly used in:
- web servers (FastAPI, Fastify, Express/Nest adapters)
- observability and distributed tracing (OpenTelemetry)
- structured logging/correlation IDs
What this maps to per runtime
- Python uses
ContextVars(contextvars.ContextVar). - TypeScript (Node/Bun) uses
AsyncLocalStorage. - Rust uses normal Rust context propagation (
dcontextsnapshots are captured at emit time and restored for handlers). - Go uses
context.Contextvalues captured withEmitWithContext(...)and restored during handler execution.
emit(...) time and restores it when handlers execute. Go propagates the explicit context.Context passed to EmitWithContext(...). In both cases, handler code sees the same request-local values.
Why this matters
Without propagation, handler code often loses request-local state after async boundaries and queue scheduling.With propagation, event handlers can log/trace as if they were still running in the original request scope.
- Python
- TypeScript
- Rust
- Go
Web server style examples
These patterns are typical in frameworks where each incoming request gets a request-local context object.- Python
- TypeScript
- Rust
- Go
Browser runtime note
AsyncLocalStorage is a Node/Bun API and is not available in browser runtimes.
In browsers:
- AbxBus still works normally for events.
- ambient async context propagation via
AsyncLocalStorageis not available. - pass correlation/tracing fields explicitly in event payloads when you need that metadata.
AsyncLocalStorage/ContextVar state; pass the request context at emit time with bus.EmitWithContext(...) or event.EmitWithContext(...) and AbxBus propagates that context.Context into handlers and awaited child events.