Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support continuation/async local storage #7010

Closed
matthewadams opened this issue Aug 11, 2020 · 21 comments · Fixed by #24402
Closed

Support continuation/async local storage #7010

matthewadams opened this issue Aug 11, 2020 · 21 comments · Fixed by #24402
Labels
cli related to cli/ dir node API polyfill Related to various "node:*" modules APIs node compat

Comments

@matthewadams
Copy link
Contributor

This issue is basically requesting the deno equivalent of https://www.npmjs.com/package/@northscaler/continuation-local-storage or https://nodejs.org/dist/latest-v14.x/docs/api/async_hooks.html#async_hooks_class_asynclocalstorage, with the additional feature as described at nodejs/node#32062 (comment).

Without this, patterns like aspect-oriented programming (AOP) would be extremely difficult to implement. Here's an example of an AOP implementation based on @northscaler/aspectify that depends on continuation local storage to pull off its task: https://www.npmjs.com/package/@northscaler/securable-trait#security-via-aspect-oriented-programming-aop

@MarkTiedemann
Copy link
Contributor

Not sure I understand your feature request. Can you sketch the API?

I noticed that you created the @northscaler/continuation-local-storage module. Why do you want this module (or something similar) to be a part of Deno (I presume, the standard library) rather than a third-party module?

@matthewadams
Copy link
Contributor Author

Not sure I understand your feature request. Can you sketch the API?

The API would be similar to AsyncLocalStorage from Node.js: https://nodejs.org/dist/latest-v14.x/docs/api/async_hooks.html#async_hooks_class_asynclocalstorage. No need to sketch the API here. Just steal take inspiration from that.

I noticed that you created the @northscaler/continuation-local-storage module. Why do you want this module (or something similar) to be a part of Deno (I presume, the standard library) rather than a third-party module?

It could be a third-party module, it could be part of Deno. In any case, the primitives upon which the module would be based must be there: the deno equivalent of async_hooks. I can assure you that if AsyncLocalStorage is part of Deno, developers are going to have more confidence in its implementation. If it's not part of Deno but published as a third-party module from the core Deno team, that would also be favorable. I suppose that the the Deno async_hooks equivalent should be part of Deno itself, and the module that end users consume could be a third-party module or part of Deno. Should there be two issues to track here, then? One for the Deno equivalent of async_hooks and this one for the Deno equivalent of AsyncLocalStorage?

In any case, having this library is a key enabling technology for use cases like the AOP one I referenced above. IMHO, AsyncLocalStorage is as important to me in Deno as ThreadLocal is to Java, and deserves the consideration of being included in the core platform.

@ry Can you weigh in here?

@ry
Copy link
Member

ry commented Aug 13, 2020

I totally missed the news on AsyncLocalStorage. Looks very useful.

I worry a lot about adding browser incompatible APIs. Is there any hope of doing AsyncLocalStorage in the browser?

@caspervonb

This comment has been minimized.

@ry
Copy link
Member

ry commented Aug 13, 2020

I don't think that's related AFAICT @caspervonb - it's just a typical kv storage not a "green thread local storage" or however you want to describe AsyncLocalStorage.

The "LocalStoarge" part of "AsyncLocalStorage" is very confusing. They are rather distinct APIs and shouldn't be using the same name.

@caspervonb

This comment has been minimized.

@vdeturckheim
Copy link

vdeturckheim commented Aug 13, 2020

@ry I believe there is an initiative to revive zones but it might take a while before going there.
If there is still a plan to support all Node.js stable APIs in Deno, one strategy could be to wait for AsyncLocaStorage to become stable and port it then. I plan to open a PR to move this to stable (in node) in the next couple months.

@matthewadams
Copy link
Contributor Author

matthewadams commented Aug 13, 2020

The "LocalStoarge" part of "AsyncLocalStorage" is very confusing. They are rather distinct APIs and shouldn't be using the same name.

@ry Yeah, I'm used to the Java name ThreadLocal. I'd be happy if Deno called it AsyncLocal or ContinuationLocal, personally. I will use the term AsyncLocal to mean Deno's version of Node.js's AsyncLocalStorage for the rest of this comment.

@vdeturckheim I'd ask you to not wait until AsyncLocalStorage is stable in Node.js before porting. You could keep Deno's AsyncLocal in experimental status the whole time so that we can use it & provide feedback. Then, after AsyncLocalStorage goes stable, you can later make AsyncLocal stable in Deno. One thing, though: make sure you're considering the ease-of-use ideas presented & being discussed at nodejs/node#32062 (comment) and below.

@lucacasonato lucacasonato added cli related to cli/ dir suggestion suggestions for new features (yet to be agreed) labels Aug 17, 2020
@xialvjun
Copy link

xialvjun commented Apr 14, 2021

I totally missed the news on AsyncLocalStorage. Looks very useful.

I worry a lot about adding browser incompatible APIs. Is there any hope of doing AsyncLocalStorage in the browser?

@ry https://www.npmjs.com/package/zone.js is for browser.

What's a zone? A Zone is an execution context that persists across async tasks. You can think of it as thread-local storage for JavaScript VMs.

Another issue about this is #5638 . It seems you didn't participate in that issue, so I @ you.

@kitsonk
Copy link
Contributor

kitsonk commented Apr 14, 2021

Zones are dead as a TC39 proposal. There maybe an initial to revive it, but if anything it will be a cut down version of what was originally proposed, and therefore totally incompatible with what currently exists. Therefore there really isn't anything suitable that is standards based we can consider.

@xialvjun
Copy link

There is a PR #8209 , but it's not for browser.

@winston0410
Copy link

Is there any update on this feature?

@kitsonk
Copy link
Contributor

kitsonk commented Sep 4, 2022

No. As stated clearly above, there is not a web standard that would introduce this, and it depends upon a withdrawn TC39 proposal. Given that Node.js async_hooks is still experimental, there is no web standard for this whole domain of stuff and there are a lack of underlying standard JavaScript APIs to implement it, it isn't going to happen any time soon.

Just commenting "any updates" is annoying, because it requires the maintainers to check out and see if there was actually some important information that was missed. If you want to voice support for something, add your 👍 to the top of the issue.

@zkulbeda
Copy link

Node.js AsyncLocalStorage is stable with run and getStore functions. docs

const storage = new AsyncLocalStorage();

function logWithId(msg) {
  const id = storage.getStore();
  console.log(`${id !== undefined ? id : '-'}:`, msg);
}

const result = await storage.run(crypto.randomUUID(), async () => {
  logWithId('start');
  await new Promise((resolve) => {
    setTimeout(() => {
      logWithId('finish');
      resolve();
    }, 200);
  });
  return "ok";
});

// result === "ok"
// storage.getStore() === undefined

@tom-sherman
Copy link

tom-sherman commented Dec 7, 2022

There is an async context proposal but it's pre Stage 1

https://github.com/legendecas/proposal-async-context

It also appears that Cloudflare will end up shipping a similar API in workers

cloudflare/workerd#208

@benjamn
Copy link

benjamn commented Jan 23, 2023

I just opened tc39/proposal-async-context#17 over at the AsyncContext proposal repository, sharing my Deno-based native implementation of the current proposal.

If you have Docker installed, you can docker pull benjamn/deno:async-context (a mere 162MB, thanks to Deno being a standalone static binary!) and then drop yourself into a Deno REPL where AsyncContext is globally defined:

docker run -it --rm benjamn/deno:async-context repl

I would encourage anyone who has commented here to copy/paste this code into the REPL:

const c = new AsyncContext();
c.run(123, async () => {
  console.log("before await", c.get());
  const awaitResult = await new Promise(resolve => {
    setTimeout(() => resolve(c.get() + 111), 20);
  });
  console.log("after await", c.get(), { awaitResult });
})

Please note, I am not making any recommendation that AsyncContext should become an official part of Deno, but I figured I could bring new focus to this discussion by sharing a toy implementation.

If you think I might have messed something up with my changes to Deno, there's also a benjamn/deno:unmodified image you can use for comparison (no AsyncContext provided).

Please let me know what you think!

@bartlomieju
Copy link
Member

FYI a polyfill for AsyncLocalStorage is now available in https://deno.land/std/node/async_hooks.ts. @lucacasonato is working through the comitees on AsyncContext proposal.

@selbyk
Copy link

selbyk commented Apr 7, 2023

@bartlomieju https://deno.land/std/node/async_hooks.ts 404s after 0.177.0. Any word on this?

@bartlomieju
Copy link
Member

You can use it by importing it directly from node:async_hooks module:

import { AsyncLocalStorage } from "node:async_hooks";

@yoshixmk
Copy link

@bartlomieju Is it possible to get support for async_hooks.executionAsyncResource() ?

I found in DataDog/dd-trace-js#1892 (comment)

@bartlomieju
Copy link
Member

@yoshixmk as it stands we don't plan to add support for that API. Currently we only want to support AsyncLocalStorage.

@ry ry mentioned this issue May 8, 2024
3 tasks
@devsnek devsnek added node compat and removed suggestion suggestions for new features (yet to be agreed) labels Jul 5, 2024
@devsnek devsnek added the node API polyfill Related to various "node:*" modules APIs label Jul 5, 2024
@devsnek devsnek closed this as completed in 3a1a1cc Aug 2, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cli related to cli/ dir node API polyfill Related to various "node:*" modules APIs node compat
Projects
None yet
Development

Successfully merging a pull request may close this issue.