tc39/proposal-async-context

Limit the proposal to Promise and async/await only?

dfahlander opened this issue ยท 6 comments

This proposal is so great. It fills the black whole - a missing link between promise flows - and I believe it fills a really important missing piece in modern JS.

The described use cases are great - priority tasks, logging contexts etc. But I also believe this proposal could improve many user-land libraries and frameworks and make things possible that weren't before:

  • React will be able to support async components on the client (making it in-pair with their new server components) as React.Context could work thanks to this proposal. All the dancing around async fetching using useEffect() or suspense would suddenly be a piece of cake and drag us back to plain await calls within the components.

  • Dexie.js (my library) will be able to track liveQueries and transactions without having to do it using its own tricks.

...probably a lot more libraries and frameworks that are context aware - that could go all-in on async await without having to re-invent the wheel.

That said, I think the biggest win of this proposal is Promise and async/await. All whatwg related features (especially the discussion around EventTarget #19) could potentially generate some questions that could take time and effort from the core proposal. In the worst case, stall this proposal from advancement.

Could it be a thought to put whatwg-related changes as a non-goal for this proposal and limit it to Promise and async/await only as a first step?

ljharb commented

Anything that works for async/await should also work for Promises, and vice-versa.

I don't think this can be done as a first step, because you could write code that relies on, for example, event listener callbacks not having the same context as the function that defines them, and that code would break. "Don't break the web" is a core guideline for both JS and the web platform, and leaving this decision for later risks breakage.

I don't think this can be done as a first step, because you could write code that relies on, for example, event listener callbacks not having the same context as the function that defines them, and that code would break. "Don't break the web" is a core guideline for both JS and the web platform, and leaving this decision for later risks breakage.

That's a good point. I guess my point is: In case there would be any kind of show-stoppers in whatwg that would stall or stop this proposal - better to limit it in a very precise set of APIs (Promises/async/await as the minimal set) and make sure it gets out.

Adding support later could be done without breaking the web though if requiring new parameters to capture async contexts.

That's a good point. I guess my point is: In case there would be any kind of show-stoppers in whatwg that would stall or stop this proposal - better to limit it in a very precise set of APIs (Promises/async/await as the minimal set) and make sure it gets out.

Adding support later could be done without breaking the web though if requiring new parameters to capture async contexts.

In September, I met together with various interested parties from the web platform side of things in TPAC, and while this was only an initial meeting trying to clarify doubts and discuss some of the various use cases for context propagation through events, I didn't hear any objections or concerns related to the web platform integration. (There was one concern about AsyncContext being a potential memory leak footgun, but that's about the JS side of it, so I doubt it would block the web spec work if TC39 approves.)

That said, you can never guarantee that there will be no further objections, especially as the proposal moves forward and gets more eyes on it. I think we could decide on various tiers of API support in case this happens, since there are web APIs (like setTimeout/setInterval and queueMicrotask) for which using the registration-time context seems very much uncontroversial.

Edit: But I think it's very unlikely that we end up needing these tiers of support, especially since we're already starting to work on the HTML integration.

Qard commented

Limiting it to promises and async/await would make it useless to APM, which is by far the biggest segment of users asking for this capability.

Also, from a technical standpoint, it's rather dangerous to half-implement it like that as you could get context leaks all over the place due to unsupported things not explicitly escaping the context. There are many cases like Node.js triggering the microtask checkpoint recursively, or http.Agent doing connection pooling, where unrelated execution continues within the same scope and kicks of new execution which absolutely should not be linked to that prior context. There needs to be tools for runtimes to escape the context around implementation details like that, and there needs to linkage for execution internal to a promise runner for it to be useful for APM. You can't just stitch around a whole big chunk of execution. Users will definitely try to acquire context data in there and then be surprised when they can't get it. Context management is kind of an all-or-nothing thing.

Defining the basic rule for Web API integration with async context is required for the proposal to advance in stages and can not be excluded from the proposal scope. However, whether or not a particular web API should provide additional options to capture arbitrary context will be deferred to its spec editors and working groups.

Closing as not planned.