01:50 | <Steve Hicks> | Would we expose any way to access the flow context from a callback? It may not be particularly relevant from most DOM APIs, but Promise 's resolution context is quite relevant, and I worry about userland APIs from a consistency standpoint (either they'll use Snapshot.wrap for consistency's sake with all the builtins, or else they cause a lot of confusion). And many users of userland APIs (signals, etc) will want access to the flow context. If all we have is lexical context for everything, it's not particularly useful for us, nor for APM - I'm not sure who the user would be at that point. |
06:55 | <littledan> | Would we expose any way to access the flow context from a callback? It may not be particularly relevant from most DOM APIs, but |
06:56 | <littledan> | then APMs can patch all entry points to set event listeners to watch for a particular variable on that other snapshot and do something with it |
07:22 | <littledan> | Yeah, agreed that two type of variables could be a solution. Did you have a chance talking about |
17:16 | <Steve Hicks> | Yes, I think (at a minimum) we should do this for a number of Events, make an extra property which is an AsyncContext.Snapshot taken from when it was resolved. So this would be for "lexical" variables as well. await and Promise.then are both lexically bound (which I mostly agree with - the former somewhat moreso than the latter, but overall I think it makes sense), there's no way to get at the promise's resolution context, and that's very relevant for understanding "follows from". Would we expose some sort of static function to grab it? Promise.resolutionSnapshot(promise) ? Snapshot.fromPromise(promise) ? Could something like that work more generally for other cases like events? |
17:20 | <Steve Hicks> | Assuming promises store their resolution context somewhere, is there a reasonable way to preserve it when operating on the promise? I'm imagining wanting to wrap a function fn such that Snapshot.from(p1.then(fn)) === Snapshot.from(p1) and Snapshot.from(p2.then(fn)) === Snapshot.from(p2) ... but without having access to the promise itself (just the resolved value), I don't see any way to write such a function. |
17:21 | <Steve Hicks> | This seems to still argue for something more general, like a nullary Snapshot.cause() or something |
17:22 | <Steve Hicks> | (which then sends us back down the rabbit-hole of whether this is a stack of contexts or just a back-and-forth previous context, etc) |
17:27 | <Steve Hicks> | Finally, I do think it's worth seriously considering the likely real-world ramifications of the default-lexical decision in terms of what concrete code will be written in the 1-2 years after the standard lands. Where will pepole be adding wrap() calls, and where will people be digging up causal snapshots, etc? Would having rolled all that out cause undue problems in the future if we decided to make a FlowVariable, since now everybody is mucking with these global snapshots everywhere, which (as Stephen Belanger points out) is the thing you shouldn't be doing in order for the flow context to actually do the right thing and not get wrecked by intermediate subtask calls. |
21:16 | <littledan> | I suggest we come up with a common name to use for the instance method/getter where the originating context is |
21:18 | <littledan> | My preference is that promises, in particular, would not maintain this information, at least at first. We could consider adding it later, but it might be more burden to implement than its value |
21:19 | <littledan> | There are a few cases where it is very important to present this information, eg unhandled rejections |
21:19 | <littledan> | Finally, I do think it's worth seriously considering the likely real-world ramifications of the default-lexical decision in terms of what concrete code will be written in the 1-2 years after the standard lands. Where will pepole be adding |
21:21 | <Steve Hicks> | Right, so we already need to keep track of resolution context for rejected promises - do you anticipate it's much harder to keep for all promises? |
21:23 | <Steve Hicks> | I don't know how far a common name will get us. It only makes sense when you've got an object to look it up on. What about mutation observers? Its callback is passed an array and the observer itself, neither of which has a convenient place to hang a flow snapshot. |
21:25 | <Steve Hicks> | The underlying concept of "what was the context before this callback was run?" is pretty general and has no specificity to events (though it's not quite the right concept for restoring the resolution context of promises...) - so it seems a bit unnatural to tie it to that. |
21:27 | <littledan> | I don't know how far a common name will get us. It only makes sense when you've got an object to look it up on. What about mutation observers? Its callback is passed an array and the observer itself, neither of which has a convenient place to hang a flow snapshot. |
21:29 | <Andreu Botella> | Right, so we already need to keep track of resolution context for rejected promises - do you anticipate it's much harder to keep for all promises? |
21:29 | <Andreu Botella> | and that function then enqueues a task on the event loop that fires the event |
21:29 | <Andreu Botella> | so it happens outside of the JS engine |
21:30 | <littledan> | Right, so we already need to keep track of resolution context for rejected promises - do you anticipate it's much harder to keep for all promises? |
21:30 | <littledan> | the way this currently works in the spec and in V8 is that an embedder function is called synchronously when the unhandled rejection happens |
21:31 | <Andreu Botella> | for a promise-returning web API, you mean? |
21:32 | <Andreu Botella> | the context would be set when rejecting the promise |
21:56 | <littledan> | the context would be set when rejecting the promise |
23:05 | <Steve Hicks> | You lost me with the bit about allocation-time. I think polyfilling the causal snapshots is going to be a nightmare, but I guess I can maybe see an argument for exposing these different causal snapshots in different ways if they end up meaning different things. That said, I know for sure that signals will want access to causal context and there's no event object there - we should consider what precedent this sets and what options would be open to that proposal to be consistent. |