-
Notifications
You must be signed in to change notification settings - Fork 107
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix: Wake event loop when dynamic import promise resolves (#769)
Fixes a hang that could occur when a module contained a dynamic import that doesn't resolve immediately, and there was a pending op outstanding. The original reproduction (ref denoland/deno#24098) effectively boiled down to this: ```ts // main.ts Deno.serve(async function (_req: Request): Promise<Response> { await import("./repro.ts"); console.log("imported module"); return new Response("done"); }); // repro.ts await new Promise<void>((resolve) => setTimeout(resolve, 0)); console.log("module executed"); ``` Upon getting a request, it would hang when trying to import `"repro.ts"`. What was happening here was that `Deno.serve` created an op (`op_http_serve`) that stayed pending indefinitely, so we [assumed](https://github.com/denoland/deno_core/blob/4beb54e862805be6b2c4d8fb2bfc49ea72705799/core/runtime/jsruntime.rs#L1816C6-L1822C9) that we would poll again, but that didn't actually hold. Unlike non-dynamic module evaluation, we weren't waking the event loop for polling when the dynamic import evaluation promise resolved. The fix here is to attaching callbacks to the dynamic import promise to wake the event loop when it resolves, similar to what we do for normal module evaluation.
- Loading branch information
1 parent
eeecea2
commit 68c4885
Showing
9 changed files
with
62 additions
and
25 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
15 changes: 15 additions & 0 deletions
15
testing/integration/dyn_import_no_hang/dyn_import_no_hang.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. | ||
import { asyncNeverResolves } from "checkin:async"; | ||
|
||
// make a promise that never resolves so we have | ||
// a pending op outstanding | ||
const prom = asyncNeverResolves(); | ||
|
||
// import a module, with the key being that | ||
// this module promise doesn't resolve until a later | ||
// tick of the event loop | ||
await import("./dynamic.js"); | ||
console.log("module imported"); | ||
|
||
// unref to let the event loop exit | ||
Deno.core.unrefOpPromise(prom); |
2 changes: 2 additions & 0 deletions
2
testing/integration/dyn_import_no_hang/dyn_import_no_hang.out
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. | ||
await new Promise((resolve) => { | ||
// Resolve the promise after one tick of the event loop. | ||
setTimeout(() => { | ||
resolve(); | ||
}, 0); | ||
}); | ||
console.log("module executed"); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters