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

Hyper Minimalistic Spec - Unopinionated Async Context #110

Open
iliasbhal opened this issue Jan 21, 2025 · 2 comments
Open

Hyper Minimalistic Spec - Unopinionated Async Context #110

iliasbhal opened this issue Jan 21, 2025 · 2 comments

Comments

@iliasbhal
Copy link

iliasbhal commented Jan 21, 2025

I am nobody and this is going to be a bit brutal lol 🏳️ Please bear with me πŸ™.

What if we remove almost everything from the proposal and keep the strict minimum when it comes to the API.

There is a lot of opinions about what should the feature look like.
But in reality, the only thing that is needed, to implement almost all proposed features, is a very simple API that should provide:

  • Ability to know in which context the code is in from the JS code.
  • Ability to walk the "async stack" upward from the JS code.
// Just an example API using getters
const stack = AsyncContext.current; // <- How to get the current stack object.
stack.origin.origin.origin.origin // <- How to traverse the stack from "async stack" to "async stack".

These two features alone allows to implement everything else. That will allow library developers to build their own API on top of it to satifies different kind of constraints, objectives or opinions.

Note: this would have advantage to have a zero performance cost on the native side (If I'm not mistaken), since the engine already knows where to forward errors in an async call, it could repurpose the same code to surface the current async context using getters from the JS land.

Note2: I refactored the polyfill I created to showcase exactly that: https://github.com/iliasbhal/simple-async-context

Let me know what you think πŸ™

@andreubotella
Copy link
Member

andreubotella commented Jan 21, 2025

  1. If you have multiple libraries that need to use the context, they'll be stepping on each others' toes. With this proposal, each library would be using its own AsyncContext.Variable(s), which would
  2. One of the goals of this proposal is that, if you call a function (whether synchronously or asynchronously), the context cannot have changed under your feet. This allows a sync callee to change the context and not restore it before returning.
  3. I'm not convinced that this wouldn't have a performance cost. An async function returns a promise, and throwing an uncaught error from it means rejecting the promise. The error is not forwarded through async functions, it is forwarded through promises. I guess we could store the context internally in the Promise object, and somehow make it available in async functions, but the vast majority of promises would not have a need for this field.
  4. This would cause memory leaks, because if an async function is called without being awaited, the functions upwards in its "async stack" might have returned long ago, but their contexts must be preserved.

@mhofman
Copy link
Member

mhofman commented Jan 21, 2025

This seems it would violate the dynamic scoping constraints this proposal attempts to respect. See https://github.com/tc39/proposal-async-context/blob/master/SCOPING.md and some of the discussion at endojs/endo#1424

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants