From 073cf3a84992a30fc820ea5df4f86c9cd8f6361a Mon Sep 17 00:00:00 2001 From: Sergi Gonzalez <31130069+TheHypnoo@users.noreply.github.com> Date: Fri, 30 Oct 2026 13:18:22 +0100 Subject: [PATCH 1/2] docs(changelog): backfill fragment for deferred async destroy ordering --- changelog.d/PENDING-async-destroy-defer.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog.d/PENDING-async-destroy-defer.md diff --git a/changelog.d/PENDING-async-destroy-defer.md b/changelog.d/PENDING-async-destroy-defer.md new file mode 100644 index 00000000000..b44a88ab446 --- /dev/null +++ b/changelog.d/PENDING-async-destroy-defer.md @@ -0,0 +1 @@ +**A queued async-resource `destroy` now waits for the enclosing execution scopes to emit their `after` hook, and only for the resources those scopes actually own.** A timer's callback checkpoint can run before that callback's own `after`, so an interval that cleared itself from inside its callback — or any collection that queued destruction during a nested scope — could deliver `destroy` for a resource whose `before`/`after` pair had not closed yet, and a nested scope could observe a resource destroyed while it was still executing. `drain_gc_destroy_queue` no longer drains the queue wholesale inside an active scope: it retains the queued entries whose serial is still on the execution stack (plus those whose async job domain is not eligible yet) and delivers the rest, so ready resources unrelated to the active scope are not held behind it. Regression coverage is the node-suite case `test-parity/node-suite/async_hooks/hooks/interval-cancel-checkpoint-lifecycle.ts`: the interval clears itself inside its own callback, and `process.nextTick` and `queueMicrotask` running inside that scope both observe the interval's `destroy` count still at 0; the lifecycle is exactly `before>after>destroy`, no resource destroys twice, and a sibling `setTimeout` cancelled in the same scope still destroys exactly once. From f85b6d20db6365c65de2112c441c10abfe0f463d Mon Sep 17 00:00:00 2001 From: Sergi Gonzalez <31130069+TheHypnoo@users.noreply.github.com> Date: Fri, 30 Oct 2026 13:18:48 +0100 Subject: [PATCH 2/2] changelog: fragment named for its PR --- ...ENDING-async-destroy-defer.md => 13536-async-destroy-defer.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename changelog.d/{PENDING-async-destroy-defer.md => 13536-async-destroy-defer.md} (100%) diff --git a/changelog.d/PENDING-async-destroy-defer.md b/changelog.d/13536-async-destroy-defer.md similarity index 100% rename from changelog.d/PENDING-async-destroy-defer.md rename to changelog.d/13536-async-destroy-defer.md