From 81498ecbea17186de4733c130dda9130ccd6b5de Mon Sep 17 00:00:00 2001 From: Sergey Tatarintsev Date: Wed, 28 Dec 2022 12:33:43 +0100 Subject: [PATCH 1/2] test: Memory leak reproduction for futures --- memory-testing/index.mjs | 1 + memory-testing/returns-future.mjs | 26 ++++++++++++++++++++++++++ memory-testing/src/lib.rs | 3 +++ 3 files changed, 30 insertions(+) create mode 100644 memory-testing/returns-future.mjs diff --git a/memory-testing/index.mjs b/memory-testing/index.mjs index 332a5477..b3d3d869 100644 --- a/memory-testing/index.mjs +++ b/memory-testing/index.mjs @@ -5,3 +5,4 @@ await createSuite('tokio-future') await createSuite('serde') await createSuite('tsfn') await createSuite('buffer') +await createSuite('returns-future') diff --git a/memory-testing/returns-future.mjs b/memory-testing/returns-future.mjs new file mode 100644 index 00000000..5497ddc3 --- /dev/null +++ b/memory-testing/returns-future.mjs @@ -0,0 +1,26 @@ +import { createRequire } from 'module' + +import { displayMemoryUsageFromNode } from './util.mjs' + +const initialMemoryUsage = process.memoryUsage() + +const require = createRequire(import.meta.url) + +const api = require(`./index.node`) + +async function main() { + let i = 1 + // eslint-disable-next-line no-constant-condition + while (true) { + await api.returnsFuture() + if (i % 100000 === 0) { + displayMemoryUsageFromNode(initialMemoryUsage) + } + i++ + } +} + +main().catch((e) => { + console.error(e) + process.exit(1) +}) diff --git a/memory-testing/src/lib.rs b/memory-testing/src/lib.rs index 1b0c432d..85c87ef2 100644 --- a/memory-testing/src/lib.rs +++ b/memory-testing/src/lib.rs @@ -171,3 +171,6 @@ pub fn buffer_pass_through(buffer: Buffer) -> Buffer { pub fn array_buffer_pass_through(array_buffer: Uint8Array) -> Uint8Array { array_buffer } + +#[napi] +pub async fn returns_future() {} From b7ba0688539ab173bda8f73c39ba9f254870f408 Mon Sep 17 00:00:00 2001 From: LongYinan Date: Wed, 28 Dec 2022 22:28:47 +0800 Subject: [PATCH 2/2] test: fix memory test assertion --- memory-testing/test-util.mjs | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/memory-testing/test-util.mjs b/memory-testing/test-util.mjs index 11166c81..659f2494 100644 --- a/memory-testing/test-util.mjs +++ b/memory-testing/test-util.mjs @@ -44,14 +44,19 @@ export async function createSuite(testFile, maxMemoryUsage) { const stats = await container.stats() let shouldAssertMemoryUsage = false - - const initialMemoryUsage = await new Promise((resolve, reject) => { + let initialMemoryUsage + await new Promise((resolve, reject) => { + const initialDate = Date.now() stats.on('data', (d) => { const { memory_stats } = JSON.parse(d.toString('utf8')) - resolve(memory_stats.usage) + if (Date.now() - initialDate > 10000 && !shouldAssertMemoryUsage) { + resolve() + initialMemoryUsage = memory_stats.usage + shouldAssertMemoryUsage = true + } if (shouldAssertMemoryUsage && memory_stats?.usage) { const memoryGrowth = memory_stats.usage - initialMemoryUsage - if (memoryGrowth > maxMemoryUsage ?? initialMemoryUsage) { + if (memoryGrowth > (maxMemoryUsage ?? initialMemoryUsage)) { console.info( chalk.redBright( `Potential memory leak, memory growth: ${prettyBytes( @@ -72,8 +77,6 @@ export async function createSuite(testFile, maxMemoryUsage) { await sleep(60000) - shouldAssertMemoryUsage = true - try { await container.stop() await container.remove()