-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Revert "feat(cloudflare): Introduce lock instrumentation for context.waitUntil to prevent multiple instrumentation (#17539)"
#17666
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,38 @@ | ||
| import type { ExecutionContext } from '@cloudflare/workers-types'; | ||
|
|
||
| type FlushLock = { | ||
| readonly ready: Promise<void>; | ||
| readonly finalize: () => Promise<void>; | ||
| }; | ||
|
|
||
| /** | ||
| * Enhances the given execution context by wrapping its `waitUntil` method with a proxy | ||
| * to monitor pending tasks, and provides a flusher function to ensure all tasks | ||
| * have been completed before executing any subsequent logic. | ||
| * | ||
| * @param {ExecutionContext} context - The execution context to be enhanced. If no context is provided, the function returns undefined. | ||
| * @return {FlushLock} Returns a flusher function if a valid context is provided, otherwise undefined. | ||
| */ | ||
| export function makeFlushLock(context: ExecutionContext): FlushLock { | ||
| let resolveAllDone: () => void = () => undefined; | ||
| const allDone = new Promise<void>(res => { | ||
| resolveAllDone = res; | ||
| }); | ||
| let pending = 0; | ||
| const originalWaitUntil = context.waitUntil.bind(context) as typeof context.waitUntil; | ||
| context.waitUntil = promise => { | ||
| pending++; | ||
| return originalWaitUntil( | ||
| promise.finally(() => { | ||
| if (--pending === 0) resolveAllDone(); | ||
| }), | ||
| ); | ||
| }; | ||
| return Object.freeze({ | ||
| ready: allDone, | ||
| finalize: () => { | ||
| if (pending === 0) resolveAllDone(); | ||
| return allDone; | ||
| }, | ||
| }); | ||
| } | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Bug: Instrumentation Overlap Causes Memory LeaksThe |
||
This file was deleted.
This file was deleted.
This file was deleted.
This file was deleted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Potential bug: The
makeFlushLockfunction overwrites the nativecontext.waitUntilmethod. Other parts of the code attempting to bind to this new function will fail, causing an "Illegal invocation" error.Description: The
makeFlushLockfunction directly mutates the originalExecutionContextby overwriting the nativewaitUntilmethod with a JavaScript wrapper. Elsewhere in the code,context.waitUntil.bind(context)is called. Attempting to bind the new JavaScript function, which wraps the original native method, breaks thethiscontext required by the Cloudflare Workers runtime. This results in aTypeError: Illegal invocationwhenwaitUntilis called, causing the worker to crash. The removal of thecopyExecutionContextutility exacerbates this by ensuring multiple handlers operate on the same mutated context object.Suggested fix: Instead of mutating the original
contextobject,makeFlushLockshould return a newwaitUntilfunction and other related properties. The caller can then use this new object without affecting the global context. Alternatively, restore a mechanism similar to the removedcopyExecutionContextto provide isolated, correctly-bound contexts to different parts of the application.severity: 0.85, confidence: 0.95
Did we get this right? 👍 / 👎 to inform future reviews.