Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions lib/internal/async_local_storage/async_context_frame.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
'use strict';

const {
ObjectIs,
ReflectApply,
} = primordials;

Expand Down Expand Up @@ -53,12 +54,15 @@ class AsyncLocalStorage {
}

run(data, fn, ...args) {
const prior = AsyncContextFrame.current();
const prior = this.getStore();
if (ObjectIs(prior, data)) {
Comment thread
Flarna marked this conversation as resolved.
return ReflectApply(fn, null, args);
}
this.enterWith(data);
try {
return ReflectApply(fn, null, args);
} finally {
AsyncContextFrame.set(prior);
this.enterWith(prior);
}
}

Expand Down
1 change: 1 addition & 0 deletions test/async-hooks/test-async-local-storage-gcable.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ asyncLocalStorage.run({}, () => {

onGC(asyncLocalStorage, { ongc: common.mustCall() });
});
asyncLocalStorage.disable();
Comment thread
Flarna marked this conversation as resolved.
Outdated

asyncLocalStorage = null;
global.gc();
65 changes: 65 additions & 0 deletions test/parallel/test-async-local-storage-isolation.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
'use strict';
const common = require('../common');
const { AsyncLocalStorage } = require('node:async_hooks');
const assert = require('node:assert');

// Verify that ALS instances are independent of each other.

{
const als1 = new AsyncLocalStorage();
const als2 = new AsyncLocalStorage();

assert.strictEqual(als1.getStore(), undefined);
assert.strictEqual(als2.getStore(), undefined);

als1.run('store1', common.mustCall(() => {
assert.strictEqual(als1.getStore(), 'store1');
assert.strictEqual(als2.getStore(), undefined);

als2.run('store2', common.mustCall(() => {
assert.strictEqual(als1.getStore(), 'store1');
assert.strictEqual(als2.getStore(), 'store2');
}));
assert.strictEqual(als1.getStore(), 'store1');
assert.strictEqual(als2.getStore(), undefined);

als2.enterWith('store3');
assert.strictEqual(als1.getStore(), 'store1');
assert.strictEqual(als2.getStore(), 'store3');
}));

assert.strictEqual(als1.getStore(), undefined);
assert.strictEqual(als2.getStore(), 'store3');
}

{
Comment thread
Flarna marked this conversation as resolved.
const als1 = new AsyncLocalStorage();
const als2 = new AsyncLocalStorage();
const als3 = new AsyncLocalStorage();

als3.enterWith('store3');

als1.run('store1', common.mustCall(() => {
assert.strictEqual(als1.getStore(), 'store1');
assert.strictEqual(als2.getStore(), undefined);
assert.strictEqual(als3.getStore(), 'store3');

als2.run('store2', common.mustCall(() => {
assert.strictEqual(als1.getStore(), 'store1');
assert.strictEqual(als2.getStore(), 'store2');
assert.strictEqual(als3.getStore(), 'store3');

als1.disable();
assert.strictEqual(als1.getStore(), undefined);
assert.strictEqual(als2.getStore(), 'store2');
assert.strictEqual(als3.getStore(), 'store3');
}));
assert.strictEqual(als1.getStore(), undefined);
assert.strictEqual(als2.getStore(), undefined);
assert.strictEqual(als3.getStore(), 'store3');
}));

assert.strictEqual(als1.getStore(), undefined);
assert.strictEqual(als2.getStore(), undefined);
assert.strictEqual(als3.getStore(), 'store3');
}
Loading