13:35
<Andreu Botella>
while checking out https://github.com/tc39/proposal-async-context/pull/94, I noticed that the (current) AsyncContext.Variable semantics also has merge points
13:35
<Andreu Botella>
except you can only observe them from the unhandledrejection event
13:44
<Chengzhong Wu>
Would you mind elaborating on it? Can a property on PromiseRejectionEvent liked mentioned at https://matrixlogs.bakkot.com/TC39_General/2024-06-21#L2-L5 address that?
13:48
<Andreu Botella>
I think the background for littledan's comment there was that, when discussing events with Anne and other web platform folks in the Web Engines Hackfest, we agreed that the originating context should be exposed as a (maybe null) property on all events
13:49
<Andreu Botella>
and for ErrorEvent, that would just be the regular property, but it would need special tracking across the abrupt completions to be able to get the context in which the exception was thrown
13:50
<Andreu Botella>
but I guess for PromiseRejectionEvent, that property could be an array instead
13:50
<Andreu Botella>
function createRejectionInContext(value) {
    ctx.run(value, () => Promise.reject());
}

ctx.run("main", () => {
    // don't await or do anything with the result
    Promise.all([
        createRejectionInContext("task-0"),
        createRejectionInContext("task-1"),
        createRejectionInContext("task-2"),
        createRejectionInContext("task-3"),
    ]);
});

window.onunhandledrejection = (evt) => {
    evt.originatingContext.run(() => {
        // Could be task-[0123]. Can't be main.
        console.log(ctx.get());
    })
}
13:52
<Andreu Botella>
well, I guess in that example, with the current spec, it would always be task-0
13:54
<Andreu Botella>
but for allSettled you would definitely have a merge
13:54
<Chengzhong Wu>
There should be only one rejection event for the promise of Promise.all, and the evt.promise is the promise of Promise.all
13:54
<Andreu Botella>
yeah, you're right
13:55
<Andreu Botella>
but for Promise.allSettled and Promise.any you would have a merge
13:58
<Andreu Botella>
if you implemented the current spec as is, you'd get the context of the last promise to resolve
13:58
<Andreu Botella>
even if that last promise is fulfilled
14:02
<Andreu Botella>
that's for Promise.any
14:02
<Andreu Botella>
I didn't realize Promise.allSettled never rejected
14:03
<Chengzhong Wu>
Yeah, Promise.allSettled never rejects
14:05
<Chengzhong Wu>
if you implemented the current spec as is, you'd get the context of the last promise to resolve
https://tc39.es/ecma262/#sec-performpromiseany 27.2.4.3.1 step 4.n performs then on the iterated promises, how would it be different from a Promise.prototype.then in this case?
14:08
<Andreu Botella>
...I might need to trace through the algorithm steps after all
14:09
<Andreu Botella>
yeah, maybe there's no way to observe that after all, since you'd end up with the context in which Promise.any was called in any case
14:09
<Chengzhong Wu>
Yeah, if I understand it correctly, this is what the document described
14:12
<Andreu Botella>
...is it? Sorry, I haven't been doing any work on this proposal for the past few weeks (because of other obligations and a break I took), and enough things changed shortly before that that I'm not so sure where things stand right now
14:14
<Chengzhong Wu>
We didn't make any normative changes yet. It just wraps up the comparison of semantics.
14:42
<littledan>
I think the background for littledan's comment there was that, when discussing events with Anne and other web platform folks in the Web Engines Hackfest, we agreed that the originating context should be exposed as a (maybe null) property on all events
Once nice property of this solution, as opposed to AsyncContext.currentComputed(), is that it gives us a clear way to add more originating contexts over time without risk of breaking anyone. OTOH with currentComputed, if it would sloppily leave the previous originating context in place until the next time that there's a relevant originating context, then it would change the behavior of existing programs to add more information later. I do see the downside that it's more difficult to use, though.
16:37
<snek>
I don’t understand a principled way that we should decide which calling contexts to preserve. And the SES folks have made it clear that they see some cases of implicitly propagating the calling contexts to be an unacceptable information leak. But I don’t think losing the calling context in cases like this is a bad enough result to abandon the proposal entirely.
i saw a suggestion on the repo to have multiple kinds of variables, which seems like it could be reasonable? in theory each variable kind represents a separate list that an agent has to track so not horrifying to implement at least. i will need to learn more about these specific SES concerns though.
17:50
<Steve Hicks>
Ultimately as far as DOM APIs go, I think not having access to causal context is not a dealbreaker. I'm a little uneasy about not being able to access the resolution context for promises, but I don't have a concrete use case where we would need it. Most of the places we need access to causal context are userland scheduling APIs, and we can just implement them to preserve causal context as needed. Where this falls down is that (1) it makes it a lot harder to reason about when most builtin schedulers automatically snapshot the registration context, but many userland schedulers (seemingly arbitrarily) depart from that convention, and (2) it will be an adoption blocker for builtin signals if we implement causal context for our own signals' computeds/effects, but the eventual builtin goes along with the pattern of only exposing the registration context.
18:05
<Andreu Botella>
We've discussed the unhandledrejection event a lot, but I don't think we've ever looked at rejectionhandled in much detail
18:06
<Andreu Botella>
since that event is always queued from PerformPromiseThen, it'd have the context that's active when .then is called, right?
18:06
<Andreu Botella>
or would it make sense to do something else?
18:07
<Steve Hicks>
I didn't even realize such an event even existed... though I'd also like to see resolution context for fulfilled promises
18:08
<Steve Hicks>
(I've been gradually reading the spec but haven't gotten to Promise yet... so I can't say anything intelligent about the details unfortunately)
20:10
<littledan>
I like the multiple variable idea, especially if we can separate them into two proposals and allow the causal one to come later.