diff --git a/lib/async_hooks.js b/lib/async_hooks.js index 02362973ae1de6..758c4eab10fe83 100644 --- a/lib/async_hooks.js +++ b/lib/async_hooks.js @@ -3,6 +3,7 @@ const { NumberIsSafeInteger, ObjectDefineProperties, + ObjectIs, ReflectApply, Symbol, } = primordials; @@ -288,6 +289,10 @@ class AsyncLocalStorage { } run(store, callback, ...args) { + // Avoid creation of an AsyncResource if store is already active + if (ObjectIs(store, this.getStore())) { + return callback(...args); + } const resource = new AsyncResource('AsyncLocalStorage'); return resource.runInAsyncScope(() => { this.enterWith(store); diff --git a/test/async-hooks/test-async-local-storage-run-resource.js b/test/async-hooks/test-async-local-storage-run-resource.js index 9a7479f699246c..21bc70051bd718 100644 --- a/test/async-hooks/test-async-local-storage-run-resource.js +++ b/test/async-hooks/test-async-local-storage-run-resource.js @@ -10,8 +10,21 @@ const asyncLocalStorage = new AsyncLocalStorage(); const outerResource = executionAsyncResource(); -asyncLocalStorage.run(new Map(), () => { - assert.notStrictEqual(executionAsyncResource(), outerResource); +const store = new Map(); +asyncLocalStorage.run(store, () => { + assert.strictEqual(asyncLocalStorage.getStore(), store); + const innerResource = executionAsyncResource(); + assert.notStrictEqual(innerResource, outerResource); + asyncLocalStorage.run(store, () => { + assert.strictEqual(asyncLocalStorage.getStore(), store); + assert.strictEqual(executionAsyncResource(), innerResource); + const otherStore = new Map(); + asyncLocalStorage.run(otherStore, () => { + assert.strictEqual(asyncLocalStorage.getStore(), otherStore); + assert.notStrictEqual(executionAsyncResource(), innerResource); + assert.notStrictEqual(executionAsyncResource(), outerResource); + }); + }); }); assert.strictEqual(executionAsyncResource(), outerResource);