Skip to content

CONCEPT Cited by 1 source

Async context propagation

Definition

Async context propagation is the mechanism by which a distributed-tracing library associates a span (or other per-request context) with the asynchronous continuation of the code that started it โ€” so that spans created inside a setTimeout, fetch, Promise.then, or similar callback automatically become children of the current span without the programmer having to pass the parent span explicitly.

How it works per runtime

Node.js: AsyncLocalStorage

Node's AsyncLocalStorage API (built on async_hooks) provides runtime-native async- context propagation. OpenTelemetry JS's Node SDK uses it by default. Calls like:

await tracer.startActiveSpan("name", async () => {
  await callOtherFunction();  // callOtherFunction's spans
                              // auto-parent to "name"
});

work without passing the span explicitly. The async-local store is keyed on the Node.js async-ID tree.

Browser: no native primitive

The TC39 AsyncContext proposal is still in progress. Until it lands, the only equivalent is Zone.js, which monkey-patches global functions (setTimeout, Promise, addEventListener, etc.) to instrument async scheduling manually.

The cost of automatic propagation

Zalando's resolution

Opt out of context propagation on both client and server and pass span objects manually through function parameters, using OTel's third startup form (tracer.startSpan("name", {}, context)). This is the patterns/manual-span-passing-over-async-context pattern.

Trade-offs:

  • Loss: spans must be threaded explicitly; libraries that want to create child spans must accept a context / parent- span parameter, making the API uglier.
  • Gain (server): seamless migration from OpenTracing; no big-bang rewrite of the large existing instrumentation codebase.
  • Gain (browser): no runtime monkey-patching of customer- browser globals; lower bundle size; no Zone.js surprise interactions with third-party JS.

Seen in

Last updated ยท 501 distilled / 1,218 read