diff --git a/lib/compat/dispatcher-weakref.js b/lib/compat/dispatcher-weakref.js index a2fd0020416..463b29ca319 100644 --- a/lib/compat/dispatcher-weakref.js +++ b/lib/compat/dispatcher-weakref.js @@ -28,6 +28,8 @@ class CompatFinalizer { }) } } + + unregister (key) {} } module.exports = function () { diff --git a/lib/fetch/request.js b/lib/fetch/request.js index 85b8bb0df2f..745e0e9cc36 100644 --- a/lib/fetch/request.js +++ b/lib/fetch/request.js @@ -35,6 +35,12 @@ const { getMaxListeners, setMaxListeners, getEventListeners, defaultMaxListeners const kAbortController = Symbol('abortController') const requestFinalizer = new FinalizationRegistry(({ signal, abort }) => { + // Currently FinalizationRegistry has a problem and will explicitly call unregister. + // https://github.com/nodejs/node/issues/49344 + // https://github.com/nodejs/node/issues/47748 + // It will be removed in the future. + // The unregister key is abort. + requestFinalizer.unregister(abort) signal.removeEventListener('abort', abort) }) @@ -371,6 +377,18 @@ class Request { const abort = function () { const ac = acRef.deref() if (ac !== undefined) { + // Currently, there is a problem with FinalizationRegistry. + // https://github.com/nodejs/node/issues/49344 + // https://github.com/nodejs/node/issues/47748 + // In the case of abort, the first step is to unregister from it. + // If the controller can refer to it, it is still registered. + // It will be removed in the future. + requestFinalizer.unregister(abort) + + // Unsubscribe a listener. + // FinalizationRegistry will no longer be called, so this must be done. + this.removeEventListener('abort', abort) + ac.abort(this.reason) } } @@ -388,7 +406,11 @@ class Request { } catch {} util.addAbortListener(signal, abort) - requestFinalizer.register(ac, { signal, abort }) + // The third argument must be a registry key to be unregistered. + // Without it, you cannot unregister. + // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/FinalizationRegistry + // abort is used as the unregister key. (because it is unique) + requestFinalizer.register(ac, { signal, abort }, abort) } }