-
Notifications
You must be signed in to change notification settings - Fork 529
Description
Problem
FWIW there is no instrumentation just yet natively from Cloudflare for
waitUntil
The current waitUntil(promise: Promise<any>) signature makes it difficult to properly instrument background work with OpenTelemetry.
When passing a promise to waitUntil, the async context is captured at promise creation time:
// Async context is already captured when the IIFE is invoked
ctx.waitUntil(doBackgroundWork());When instrumenting code (especially waitUntil) for observability it could create a problem. By the time waitUntil is being instrumented, the promise already exists with its context "baked in". Child spans created inside the async function end up with the wrong parent.
Following shows a waitUntil function that starts another span right inside. Instead of having the "Subroutine" as children directly of waitUntil it uses http.server instead:
Pseudo code
waitUntil(
(async () => {
// do something
otel.startSpan((span) => {
span.name = 'Subroutine';
// this span's parent is not `waitUntil`, but the `fetch` method
});
})()
)Proposal
Add an overload that accepts a function returning a Promise:
interface ExecutionContext {
waitUntil(promise: Promise<any>): void; // existing
waitUntil(fn: () => Promise<any>): void; // new
}Usage:
ctx.waitUntil(doBackgroundWork);
// or
ctx.waitUntil(async () => {
await doBackgroundWork();
// do more
});This would allow instrumentation wrappers to (and also Cloudflare in their native observability):
- Intercept the
waitUntilcall - Establish the proper tracing context (create/activate a span)
- Invoke the function within that context
- All child spans would correctly inherit the
waitUntilspan as parent
Existing code using waitUntil(promise) continues to work unchanged. However, it would still be nice to only have one way in general and maybe move towards the new model.
Metadata
Metadata
Assignees
Labels
Type
Projects
Status