diff --git a/lib/internal/abort_controller.js b/lib/internal/abort_controller.js index b812f588c23e990..39221e58e068cf7 100644 --- a/lib/internal/abort_controller.js +++ b/lib/internal/abort_controller.js @@ -84,6 +84,32 @@ function lazyMessageChannel() { } const clearTimeoutRegistry = new SafeFinalizationRegistry(clearTimeout); +const abortControllerSignalFinalizer = new SafeFinalizationRegistry(({ signalWeakRef }) => { + // WIP on https://docs.google.com/document/d/1LvmsBLV85p-PhSGvTH-YwgD6onuhh1VXLg8jPlH32H4/edit?pli=1&tab=t.0#heading=h.7ut6obnf9fz0 + // Remove ac.signal from composed signals + // If not source signal remains in the composed signal, let it be GCed + console.log('ac was collected', signalWeakRef.deref()); + + const signal = signalWeakRef.deref(); + if (signal === undefined) { + return; + } + + signal[kDependantSignals]?.forEach((ref) => { + const dependantSignal = ref.deref(); + + if (dependantSignal === undefined) { + return; + } + + dependantSignal[kSourceSignals]?.delete(signalWeakRef); + + if (dependantSignal[kSourceSignals]?.size === 0) { + gcPersistentSignals.delete(dependantSignal); + } + }); +}); + const dependantSignalsCleanupRegistry = new SafeFinalizationRegistry((signalWeakRef) => { const signal = signalWeakRef.deref(); if (signal === undefined) { @@ -434,6 +460,9 @@ class AbortController { */ get signal() { this.#signal ??= new AbortSignal(kDontThrowSymbol); + + abortControllerSignalFinalizer.register(this, { signal: new SafeWeakRef(this.#signal) }); + return this.#signal; }