denoland / deno

A modern runtime for JavaScript and TypeScript.
https://deno.com
MIT License
93.98k stars 5.23k forks source link

AsyncLocalStorage not working with dynamic imports #25275

Closed caleblloyd closed 1 day ago

caleblloyd commented 2 weeks ago

Version: Deno 1.46.1

AsyncLocalStorage does not seem to work inside of a dynamic import in Deno, but it does in Node:

als.mjs

import { AsyncLocalStorage } from "node:async_hooks";

const als = new AsyncLocalStorage();

export function getAls() {
  return als.getStore();
}

function print() {
  console.log("ALS inside als.mjs is", getAls());
  return Promise.resolve();
}

async function run() {
  als.run("set", async () => {
    await import("./dynamic.mjs");
    await print();
  });
}

await run();

dynamic.mjs

import { getAls } from "./als.mjs";

console.log("ALS inside dynamic.mjs is", getAls());

not working in deno

$ deno run als.mjs
ALS inside dynamic.mjs is undefined
ALS inside als.mjs is set

working in node

$ node als.mjs 
ALS inside dynamic.mjs is set
ALS inside als.mjs is set
devsnek commented 2 weeks ago

I think https://github.com/denoland/deno/pull/25140 should fix this.

caleblloyd commented 2 weeks ago

That is a nice improvement! Unfortunately I do not think that fixes this particular issue though :smiling_face_with_tear: I rebased that PR on deno_core 0.307.0 and added this test case to tests/unit_node/async_hooks_test.ts:

Deno.test(async function worksWithDynamicImports() {
  const store = new AsyncLocalStorage();
  (globalThis as any).alsDynamicImport = () => store.getStore();
  const dataUrl =
    `data:application/javascript,export const data = alsDynamicImport()`;
  await store.run("data", async () => {
    const { data } = await import(dataUrl);
    assertEquals(data, "data");
  });
});

and it fails:

[async_hooks_test 005.03]     [Diff] Actual / Expected
[async_hooks_test 005.03] -   undefined
[async_hooks_test 005.03] +   "data"