From 704e78fde11e6e61321169495826b885bda18a28 Mon Sep 17 00:00:00 2001 From: Suneil Nyamathi Date: Mon, 12 Aug 2024 13:43:12 -0700 Subject: [PATCH 1/2] test: add test for memory leak --- test/fetch/response.js | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/test/fetch/response.js b/test/fetch/response.js index bd501530350..bf7dc4740a5 100644 --- a/test/fetch/response.js +++ b/test/fetch/response.js @@ -2,6 +2,8 @@ const { test } = require('node:test') const assert = require('node:assert') +const { setImmediate } = require('node:timers/promises') +const { AsyncLocalStorage } = require('node:async_hooks'); const { tspl } = require('@matteo.collina/tspl') const { Response, @@ -300,3 +302,29 @@ test('fromInnerResponse', () => { assert.strictEqual(getHeadersList(response[kHeaders]), innerResponse.headersList) assert.strictEqual(getHeadersGuard(response[kHeaders]), 'immutable') }) + +test('clone body garbage collection', async () => { + const asyncLocalStorage = new AsyncLocalStorage(); + let ref + + await new Promise(resolve => { + asyncLocalStorage.run(new Map(), async () => { + const res = new Response('hello world') + const clone = res.clone() + + asyncLocalStorage.getStore().set('key', clone); + ref = new WeakRef(clone.body) + + await res.text() + await clone.text() // consume body + + resolve(); + }) + }) + + await setImmediate() + global.gc() + + const cloneBody = ref.deref() + assert.equal(cloneBody, undefined, 'clone body was not garbage collected') +}) From 719534e0a7dce43edb317135d31aa8f52272d2df Mon Sep 17 00:00:00 2001 From: Suneil Nyamathi Date: Mon, 12 Aug 2024 14:04:01 -0700 Subject: [PATCH 2/2] lint --- test/fetch/response.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/test/fetch/response.js b/test/fetch/response.js index bf7dc4740a5..8e7c865c78e 100644 --- a/test/fetch/response.js +++ b/test/fetch/response.js @@ -3,7 +3,7 @@ const { test } = require('node:test') const assert = require('node:assert') const { setImmediate } = require('node:timers/promises') -const { AsyncLocalStorage } = require('node:async_hooks'); +const { AsyncLocalStorage } = require('node:async_hooks') const { tspl } = require('@matteo.collina/tspl') const { Response, @@ -304,21 +304,21 @@ test('fromInnerResponse', () => { }) test('clone body garbage collection', async () => { - const asyncLocalStorage = new AsyncLocalStorage(); + const asyncLocalStorage = new AsyncLocalStorage() let ref - + await new Promise(resolve => { asyncLocalStorage.run(new Map(), async () => { const res = new Response('hello world') const clone = res.clone() - - asyncLocalStorage.getStore().set('key', clone); + + asyncLocalStorage.getStore().set('key', clone) ref = new WeakRef(clone.body) await res.text() await clone.text() // consume body - resolve(); + resolve() }) })