diff --git a/meetings/2024-10/october-09.md b/meetings/2024-10/october-09.md index c73c76c..61feba0 100644 --- a/meetings/2024-10/october-09.md +++ b/meetings/2024-10/october-09.md @@ -1062,115 +1062,113 @@ ABO: So the whole point of the proposal is to have some state that gets preserve ABO: But this is because in both browsers and runtimes, promises are not the only source of asynchronicity. And things like setTimeout need to be accounted for. -ABO: So the basic idea for the web integration is that most of the web APIs that take a callback will then run it later, at a point where no context is active, where the JavaScript stack is empty. So there is only one relevant context, the one that was active when the scheduling API gets called. If you are familiar with the proposal, you know that the contexts are strictly scoped. And so if there is no active JavaScript stack, if there’s nothing on the stack, the context is empty. So we’re not dismissing that, that empty context. +ABO: So the basic idea for the web integration is that most of the web APIs that take a callback will then run it later, at a point where no context is active—where the JavaScript stack is empty. So there is only one relevant context, the one that was active when the scheduling API gets called. If you are familiar with the proposal, you know that the contexts are strictly scoped. And so if there is no active JavaScript stack, if there’s nothing on the stack, the context is empty. So we’re not dismissing that, that empty context. ABO: And for these APIs that take a callback, we store that context when the API that schedules it is called. And we restore it at the time of running the callback. And this is equivalent to wrapping the callback in `AsyncContext.Snapshot.wrap`. This can be implemented in WebIDL, which is part of how browsers implement web APIs and how they are defined in the specs. And this would work automatically, with no work needed at all for future spec additions and engine implementations. This is the case for `setTimeout`, `queueMicrotask`, `requestIdleCallback`, `schedule.postTask`, all those APIs. -ABO: Not only APIs like that, and there’s some more complexity. So observers are a common pattern in the web platform, things like `IntersectionObserver`, `MutationObserver`... These classes take a callback on the constructor, which will be called to notify of some observed change. You can register things to observe and so on. +ABO: Not all APIs like that, and there’s some more complexity. So observers are a common pattern in the web platform, things like `IntersectionObserver`, `MutationObserver`... These classes take a callback on the constructor, which will be called to notify of some observed change. You can register things to observe and so on. -ABO: The thing is, the callback might be invoked once for multiple observations—like, the observations can be queued and then the callback gets called once per event loop turn or whatever. This is different from FinalizationRegistry, where the callback is called once per observation, and so the context in which the callback is called cannot be the context of any of the observers. +ABO: The thing is, the callback might be invoked once for multiple observations—like, the observations can be queued and then the callback gets called once per event loop turn or whatever. This is different from FinalizationRegistry, where the callback is called once per observation. And so the context in which the callback is called cannot be the context of any of the observers. ABO: This actually affected the behavior we proposed for FinalizationRegistry with AsyncContext. So that is an interaction that affects the 262 spec. ABO: So here, the only reasonable option for the context in which to call the callback is to do it in the context in which the observer is constructed. But a use case for PerformanceObserver is that you might want the observation context. And those might be exposed as an `AsyncContext.Snapshot` object that is exposed in PerformanceEntry—in each of the observation entries. -ABO: And events are a more complicated case. There are one or two possible contexts for each event dispatch, or rather every time an event listener gets called. There is the registration context, which is the context that is active when `addEventListener` is called. And there is always one because you need to call `addEventListener` or set `onClick` or something like that. So there’s always a registration context. And then depending on the event, there might or might not be a dispatch context, which is the context active when the JavaScript source that caused this event is called. This can be synchronous, like the `click()` method on HTML elements fires a click event synchronously. It can be asynchronous, like if an event gets fired after a request has completed or something. And it can be missing for things like user clicks or notifications from the browser/runtime, when there is no JavaScript source for the event. +ABO: And events are a more complicated case. There are one or two possible contexts for each event dispatch, or rather for every time an event listener gets called. There is the registration context, which is the context that is active when `addEventListener` is called. And there is always one because you need to call `addEventListener` or set `onClick` or something like that. So there’s always a registration context. And then depending on the event, there might or might not be a dispatch context, which is the context active when the JavaScript source that caused this event is called. This can be synchronous, like the `click()` method on HTML elements fires a click event synchronously. It can be asynchronous, like if an event gets fired after a request has completed or something. And it can be missing for things like user clicks or notifications from the browser/runtime, when there is no JavaScript source for the event. ABO: For events that have a JavaScript source that is asynchronous, in the web platform currently there is no way to track that context automatically from the source to the final event. And there is no way to distinguish that from events that don’t have a JavaScript source. So that is not something that is built into the platform currently. -ABO: If we start tracking that context manually, it would mean changing a bunch of web specs and a bunch of browser implementations to track them manually. There is also another possibility, which is defining an automatic way to propagate the context through the spec-internal and browser-internal operations. Which is complicated. And if the context is tracked manually, adding new events in the future And about adding new events in the future might not—well, if the context is manually, adds new events might not be actively for web spec authors +ABO: If we start tracking that context manually, it would mean changing a bunch of web specs and a bunch of browser implementations to track them manually. There is also another possibility, which is defining an automatic way to propagate the context through the spec-internal and browser-internal operations. Which is complicated. And if the context is tracked manually, adding new events in the future might not be trivial for web spec authors -ABO: Our initial—with this in the background, our initial proposal for events was that the context active when an event listener is called is the registration context. So the context that is active when addEventListener or on click is called. +ABO: So with this as the background, our initial proposal for events was that the context active when an event listener is called is the registration context. So the context that is active when `addEventListener` or `onClick` is called. -ABO: And then the dispatch context can also—like, is important for some use cases. And it be exposed as a property on the event object with .… same as before, for observers. +ABO: And then the dispatch context can also be important for some use cases. And it can be exposed as a property on the event object with an `AsyncContext.Snapshot` value, same as for observers. -ABO: Now, since it might need to be tracked manually, what we initially said is that this property will not be present in all event subclasses, only presented in some, it could be a nullable property, in others. To allow an incremental rollout. And we would only initially expose this property for just a few events. Like .… +ABO: Now, since it might need to be tracked manually, what we initially said is that this property will not be present in all event subclasses. It would only be present in some. It could be a nullable property, in others to allow an incremental rollout. And we would only initially expose this property for just a few events, like the `error` and `unhandledrejection` events. -ABO: Some web platform features need a similar kind of context propagation as AsyncContext. Like, incumbent tracking, soft navigation, schedule.yield. Some of these are long-standing web platform features, some are things that are being added recently or as we speak. +ABO: Some web platform features need a similar kind of context propagation as AsyncContext. Like, incumbent realm tracking, soft navigation, `schedule.yield`. Some of these are long-standing web platform features, some are things that are being added recently or as we speak. And these could be implemented as browser-internal `AsyncContext.Variable`s. -ABO: And this could be implemented as browser-internal AsyncContext.Variables. It is not clear that the semantics for all of the features match the web integration that we’re proposing. For some of them, it’s possible that they match, but like they are different—like, for some of them, there are differences, but it’s possible they could change to have this behavior. +ABO: It is not clear that the semantics for all of the features match the web integration that we’re proposing. For some of them, it’s possible that they match. For some there are differences, but it’s possible they could change to have this behavior. For others, it could be integrated with this behavior by hooking at a lower layer, still within the browser engine, not the JavaScript engine. But these are still things that need to be figured out. -ABO: For others, it could be integrated with this behavior by looking at a lower layer, still within the browser engine, not the other engine. But these are things that need to be figured out. +ABO: And so what about the server-side? We have been talking about web integration, but this is because it was a requirement for Stage 2.7. But I think that considering Node.js and other server-side runtimes is important, and I think that the same general approach that we use for the web should also work for them. And it would be bad if server-side runtimes had completely different semantics. Especially with WinterCG and runtimes that support web platform APIs, having these different semantics depending on where the API is defined is not good. So if this is unworkable for the server-side, we want to know, and we should try to find a different way. -ABO: And so what about the server-side? This is a—we have been talking about web integration. But this is because it was a requirement for Stage 2.7. But I think that considering no JS and other runtimes is important, and I think that the same general approach that we would for the web should allow for them. And it would be bad if server-side runtimes had completely different semantics, especially with WinterCG and runtime platform APIs having this different semantics depending on where the API is defined. Like, it’s not good. So if this is unworkable for the server-side, we want to know and we should try to find a different way. +ABO: So current status. We have a PR for the web integration. There are some minor issues that I should have found time to fix, but I didn’t. But this is the main blocker for Stage 2.7 right now, as I said. The majority of the semantics are clear and uncontroversial. Except for events because they don’t seem to work for everyone. And we heard from some of the framework folks at Google, and it seems like different use cases seem to have different and conflicting requirements. So we need to figure out how to fix that. -ABO: So current status. We have a PR for the web integrations. There are some minor issues that I should have found—I should have found time to fix, but I didn’t. But this is the main blocker for Stage 2.7 right now, as I said. The majority of this semantic particulars are clear and controversial. Except for events because they don’t seem to work for everyone. And we heard from some of the framework folks at Google, and it seems like different use cases seem to have different—and conflicting requirements. So we would figure out how to, like, what to do with them. Like, how to fix that +ABO: So we will work through various alternatives, various ways that we can resolve this conflict. If this affects you, we want to hear from you and consider all relevant use cases. And we are also looking for feedback from browser engine implementers and web platform spec authors. This is not just JavaScript engine implementers, because all of this will not affect JavaScript engines. -ABO: So we will work through various alternatives to various ways to—that we can resolve this conflict. If this affects you, we want to hear from you. And consider all relevant use causes and lag for feedback from browser engine implementers and web platform spec authors. This is not just JavaScript engine implementers because all of this will not affect JavaScript engines. +ABO: So get involved, I guess. We have meetings every two weeks. Previous slide decks about AsyncContext didn’t mention you should ask us to add to the invite because I think it’s on the TC39—private. I don’t know. Just ask us. And we have a matrix channel. -ABO: So get involved, I guess. We have meetings every two weeks. Previous slides said that you can—well, previous slides about—slide decks about AsyncContext didn’t mention you should ask us to add to the invite because it’s—I think it’s on the TC39—private. I don’t know. Just ask us. And we have a matrix channel. +SYG: So I guess mostly clarifying questions, but I don’t have all this paged in. Bear with me. About the events, specifically the two contexts, the registration context and the dispatch context, like what does it mean to have two? Like, are you just saying that you need to make a decision on which context the event listener runs? Or are you saying, like, there’s a way—proposing a way to thread both contexts so the event listener itself can choose which context? -SYG: So I guess mostly clarifying questions, but I don’t have all this paged in. Bear with me. About the events, specifically the two contexts, the registration context and the—and the dispatch context, like what does it mean to have two—like, are you just saying that you need to make a decision on which context the event listener runs? Or are you saying, like, there’s a way—proposing a way to thread both contexts in the event listener itself can choose its context - -ABO: I am not proposing—so, in the PR as—like, the state of the world currently, it’s like this slide says that there are two possible contexts that could be used. Like there’s always a registration time—registration context. Some events would have a disattach context and our initial proposal was that they—you would always use by default the registration—the callback. The listener would also—would always have the run in the registration context. And then for specific types of events, you would pass the dispatch context as a property of the event. +ABO: In the PR as it is—like, the state of the world currently, it’s like this slide says that there are two possible contexts that could be used. Like there’s always a registration context. Some events would have a dispatch context, and our initial proposal was that the listener would always run in the registration context. And then for specific types of events, you would pass the dispatch context as a property of the event. SYG: What is the value of that property? It’s like the value of the async variable? -ABO: No. It’s `AsyncContext.snapshot` value +ABO: No. It’s `AsyncContext.Snapshot` value. -SYG: I see. That’s what I meant with AsyncContext. So the property would have AsyncContext.snapshot. If it originated from, like, JS user code, otherwise it’s null. +SYG: I see. That’s what you mean with an AsyncContext. So the property would have an `AsyncContext.Snapshot` if it originated from, like, JS user code, otherwise it’s null. -ABO: Or if—if the event has an async source like it originated from JS, but not – +ABO: Or if the event has an async source—like it originated from JS, but not synchronously. SYG: I see. -ABO: In that case, we’re—like, we’re not initially going to propagate that, to null in most cases. And possibly, incrementally, modify that for individual events over time. +ABO: In that case, we’re not initially going to propagate that. We might set it to null in most places, and possibly, incrementally, modify that for individual events over time. -SYG: So I am not really a—an expert on the—on the DOM side of things. Like, I assume there are a lot of events. Is it okay to add a property on all events like this? +SYG: So I am not really an expert on the DOM side of things. Like, I assume there are a lot of events. Is it okay to add a property on all events like this? ABO: In the proposal that we had, the idea would be like just incrementally – -SYG: Not event subclasses. But event instances during the time of an application of a page running, there’s a lot of events. Imagine. And we’re adding a property in every one of those with a possible snapshot? Like, I guess, you know, the snapshot will only be present if the page itself is using AsyncContext. I don’t know. Generic, seems like somehow high cost. I would like to understand it better, but I am not an expert, so .… We should get more engine people. Like, DOM side engine side +SYG: Not event subclasses. But event instances. During the time of an application of a page running, there’s a lot of events, I imagine. And we’re adding a property in every one of those with a possible snapshot? Like, I guess, you know, the snapshot will only be present if the page itself is using AsyncContext. I don’t know. Generic, seems like somehow high cost. I would like to understand it better, but I am not an expert, so we should get more engine people. Like, DOM-side engine people. -ABO: If the page itself does not use AsyncContext at all, then the way I imagine is that you would always store the registration context. But those would point to the same internal mapping, which would be an internal object in the engines. And like whether you create a JavaScript object from that, there was a possibility that you would—that you would have that property be a getter actually and only create the JavaScript object if that is needed. +ABO: If the page itself does not use AsyncContext at all, then the way I imagine is that you would always store the registration context. But those would point to the same internal mapping, which would be an internal object in the engines. And whether you create a JavaScript object from that—there was a possibility that you would have that property be a getter actually and only create the JavaScript object if that is needed. -NRO: So for context I help with the proposal, this proposal is now mostly blocked on figuring out actually how events work. When we proposed the idea of using the front of the callback in the context where given was registered—we received feedback that in some cases that should be desirable to run the code. But in the context where given was dispatched. If there is any. Mostly from frame work authors, but also because this is how, for example, a test attribution works if Chrome on the create task API works in Chrome. However, we believe one of the reasons we went with the registration time matched it, was that it’s because it is easier to implement. Because if—because to capture that without trading the snapshot a simple engine, so I know we cannot advance it for now, it’s great if like the browser people here could talk with the DOM colleagues to understand the feasibility of actually propagating the dispatch time snapshot for async events. For example, when I have XMLHttpRequest, to propagate the context from web.send to when the event listener is run. +NRO: So for context I help with the proposal, this proposal is now mostly blocked on figuring out exactly how events should work. When we proposed the idea of running the callback in the context where the event listener was registered, we received feedback that in some cases it’s desirable to run the callback in the context where the event was dispatched, if there is any. Mostly from framework authors, but also because this is how, for example, task attribution works in Chrome or how the `console.createTask` API works in Chrome. However, we believe one of the reasons we went with the registration time context was because it is easier to implement. Because you just need to capture that without propagating the snapshot through async steps in engines. -NRO: Because once we figure out what to do exactly with the events and people have to wait, then we can advance the proposal to 2.7. +NRO: So I know we cannot get an answer for this now, but it would be great if the browser people here could talk with their DOM colleagues to understand the feasibility of actually propagating the dispatch time snapshot for async events. For example, if I have an `XMLHttpRequest`, how feasible is it to propagate the context from when `.send()` is called to when the event listener is run? Because once we figure out what to do exactly with the events and once we have an answer people are happy with, then we can advance the proposal to 2.7. -DE: I want to emphasize what NRO was saying, that this proposal is done, except for the web integration. The thing is, there are other web APIs like `scheduler.yield` are being developed and in some places even shipping, which are solving the same problem of how to do context propagation. Some of these don’t have completely formal specifications for how they propagate context. We want to formalize that. In my opinion, we should propagate context in the same way across AsyncContext as well as the context tracked by these other features. Otherwise, there’s the risk that events would propagate different context variables which could be expensive at runtime. I would be hesitant to ship things incrementally unless we’re comfortable with AsyncContext. This is a debate I hope occurs on the web side. And I would appreciate the help of people who work in browsers to think through this, this sort of existence of multiple things that need the same context propagated and what the semantics of that should be. +DE: I want to emphasize what NRO was saying, that this proposal is done, except for the web integration. The thing is, there are other web APIs like `scheduler.yield` that are being developed and in some places even shipping, which are solving the same problem of how to do context propagation. Some of these don’t have completely formal specifications for how they propagate the context. And as part of this project, we want to define and formalize that. In my opinion, we should propagate context in the same way across AsyncContext as well as the context tracked by these other features. Otherwise, there’s the risk that events would have to propagate multiple different context variables, which could be expensive at runtime. I would be hesitant to ship things incrementally unless we’re comfortable with AsyncContext. This is a debate I hope occurs on the web side. And I would appreciate the help of people who work in browsers to think through this, this sort of existence of multiple things that need the same context propagated and what the semantics of that should be. -ABO: I want to mention that, well, I think I mentioned some of this before. For context tracking, this is something where it seems feasible that the semantics that are currently being used in Chrome implementation could change to be aligned with the web integration semantics we are proposing. It’s not fully clear to the folks working on it, whether that is possible. But they are willing to see, to try. `Scheduling.yield` is a slightly more complicated case. It would not require a completely different—like, having two separate mappings that need to be propagated in parallel. It just—it would have to be worked out in the—in the browser engine’s implementation of the web integration. +ABO: I want to mention that, well, I think I mentioned some of this before. For soft navigation tracking, this is something where it seems feasible that the semantics that are currently being used in the Chrome implementation could change to be aligned with the web integration semantics we are proposing. It’s not fully clear to the folks working on it whether that is possible, but they are willing to see, to try. `scheduler.yield` is a slightly more complicated case, but it would not require a completely different—like, having two separate mappings that need to be propagated in parallel. It just—it would have to be hooked in the browser engine’s implementation of the web integration. -DE: So I think it’s important to consider these interactions whether those hooks apply in all browsers before they get too far in sort of shipping the web features. There might be a misunderstanding that the web is moving faster and dynamic TC39 is slow. In this case, the slowness is not on TC39 holding back things, but rather building consensus with web stakeholders on the web semantics. That’s what I want people to come home with with this presentation: that browsers should work to solve this same (or closely related) problem. +DE: So I think it’s important that people consider these interactions, whether those hooks apply in all browsers before they get too far in shipping the web features. There might be a misunderstanding that the web is moving faster and is more dynamic, and that TC39 is slow. In this case, the slowness is not on TC39 holding back things, but rather building consensus with web stakeholders on the web semantics. That’s what I want people to come home with with this presentation: that browsers should work to solve this same (or closely related) problem. -ABO: Yeah. I am working on a document, like for the exact interactions between these web platform features. The exact semantics they need and I didn’t have to be ready for today. But I will try to finish it and make it up soon so that anyone can take a look at it and enjoy. +ABO: Yeah. I am working on a document, like for the exact interactions between these web platform features and the exact semantics they need. I didn’t have it ready for today, but I will try to finish it and make it up soon so that anyone can take a look at it and check. -SYG: I have another question just not about any of the particulars, but I want people familiar with: AsyncContext to see if this characterization is a fair characterization. My understanding of the difficulty in pinning down the semantics with all these different contexts, that it’s come up with AsyncContext but for the with soft navigation tracking and `schedule.yield` is because number of navigation tracking and `schedule.yield` are about their concrete, they are narrow APIs for like one particular concrete use case like scheduling priority. And tracking soft navigation. And because they are narrow enough, they can just choose which context is the right one to propagate. Whereas, for AsyncContext because it is programmatically controlled by user code, you have to consider all possible context that might be reasonable to propagate and difficult to nail that down because you don’t know the intent of user code. Is that a fair characterization? +SYG: I have another question—just not about any of the particulars, but I want people familiar with AsyncContext to see if this characterization is a fair characterization. My understanding of the difficulty in pinning down the semantics with all these different contexts, that it’s come up with AsyncContext but not for soft navigation tracking and `scheduler.yield` is because soft navigation tracking and `scheduler.yield` are concrete, narrow APIs for like one particular concrete use case like scheduling priority and tracking soft navigation. And because they are narrow enough, they can just choose which context is the right one to propagate. Whereas, for AsyncContext, because it is programmatically controlled by user code, you have to consider all possible things, all possible contexts that might be reasonable to propagate, and it’s difficult to nail that down because you don’t know the intent of user code. Is that a fair characterization? -ABO: I think so, yeah. And I know that for soft navigations, it has changed things and shipped things incrementally because the results are not exposed to the user. Except as a timing measurement that would be hard to influence as a developer. +ABO: I think so, yeah. And I know that soft navigation has changed things and shipped things incrementally because the results are not exposed to the user. Except as a timing measurement that would be hard to influence as a developer. -SYG: Okay. Outside of implementation reasons, like complexity reasons that you—that WebKit itself, why is it important in your opinion, to explain the propagation of soft navigation tracking and schedule path yield via AsyncContext +SYG: Okay. Outside of implementation reasons, like complexity reasons in Blink and WebKit itself, why is it important in your opinion, to explain the propagation of soft navigation tracking and `scheduler.yield` via AsyncContext? -ABO: The main reason is that we don’t have different web—like, different features at various different levels of the platform, including JavaScript that basically do the same thing except with slightly different semantics. And in—like, for the implementations, in V8 in particular, those features—not tracking and `schedule.yield` are currently using continuation, (?) preserve them better data, which we were hoping to use as—like, to replace with AsyncContext. It might end up that is—that at that replacing is fully doable, but I think it would—like, it would offer a lot more, I guess, +ABO: The main reason is that we don’t have different features at various different levels of the platform, including JavaScript, that basically do the same thing except with slightly different semantics. And for the implementation in Blink and V8 in particular, those features—well, not incumbent context, but soft navigation tracking and `scheduler.yield`, are currently using `ContinuationPreservedEmbedderData`, which we were hoping to replace with AsyncContext. It might end up that is—that at that replacing is fully doable, but I think it would—like, it would offer a lot more, I guess, -SYG: I am confused by the layer. It’s not a spec. Is it? +SYG: I am confused by the layering. CPED is not a spec. Is it? ABO: No. -DE: The fundamental issue is that implementations don’t want to carry under multiple variables to understand which context is propagated. Right now you can root everything in one thing, one extra pointer that the JavaScript engine threads through. It would have additional cost to thread two different pointers through. This will affect all implementations, not just V8. +DE: The fundamental issue is that implementations don’t want to carry around multiple variables to understand which context is propagated. Right now you can root everything in one thing, one extra pointer that the JavaScript engine threads through. It would have additional cost to thread two different pointers through. This will affect all implementations, not just V8. -DE: A difference between scheduler yield and soft navigation on one hand, and AsyncContext on the other hand, is that you can be sloppy with propagation of yield/soft navigation. And you will get approximate results that are okay enough, as long as you don’t care about consistent, reliable results across browsers. The main difference about AsyncContext is not quite that it is user programmable. But we have to nail down the precise semantics because there is so much more readily observable. If something doesn’t propagate the priority the same way by accident, you kind of recover okay. +DE: A difference between `scheduler.yield` and soft navigation on one hand, and AsyncContext on the other hand, is that you can be sloppy with propagation of yield/soft navigation. And you will get approximate results that are okay enough, as long as you don’t care about consistent, reliable results across browsers. The main difference about AsyncContext is not quite that it is user programmable. But we have to nail down the precise semantics because there is so much more readily observable. If something doesn’t propagate the priority the same way by accident, you kind of recover okay. -SYG: I still see it as a thing of a user program, because you don’t know what—like if you propagate the Wrong thing, I don’t know if it is acceptable enough for schedule.yield, you know, it is acceptable. Async.available, you can’t know, so you conserve – +SYG: I still see it as a thing of a user programmability, because you don’t know what—like if you propagate the wrong thing, you don’t know if it is acceptable enough. For `scheduler.yield`, you know because it’s not user-programmable that it is acceptable. For `AsyncContext.Variable`s, you can’t know, so you have to assume the conservative thing– -DE: If we want strong interop across browsers, then you also want the same sort of very strong well-defined semantics for scheduler.yield. You want that same thing as AsyncContext. If you don’t care if browsers have different propagation semantics for yield or different measurements for soft navigation, then you wouldn’t care about this as much. That’s the main difference. So if you just have a single browser, you know, experimenting and going ahead then it’s okay to be somewhat vague and unstable, but probably when multiple browsers want to coordinate and adopt semantics with reliable interoperability, that solution should work for AsyncContext as well. +DE: If we want interop across browsers, then you also want the same sort of very strong well-defined semantics for `scheduler.yield`. Same thing as AsyncContext. If you don’t care if browsers have different propagation semantics for yield or different measurements for soft navigation, then you wouldn’t care about this as much. That’s the main difference. So if you just have a single browser, you know, experimenting and going ahead then it’s okay to be somewhat vague and unstable, but probably when multiple browsers want to coordinate and adopt semantics with reliable interoperability, that solution should work for AsyncContext as well. CDA: We are past time. I would like to at least get to Mark’s comment before we finish. -MM: I really like your terminology of registration context and dispatch context. There are two conflicting interpretations of least surprise, to pull you in opposite derisions and verify much appreciate the choice you made. Let’s make sure I understand the consistency of this, I don’t want to use `promise.then` and `promise.then` and `promise.then` on the result of `promise.all` as examples in the language. Obviously outside the web. But the—the thing that is caused often has multiple causes. +MM: I really like your terminology of registration context and dispatch context. There are two conflicting interpretations of least surprise that pull you in opposite directions, and I very much appreciate the choice you made. Let’s make sure I understand the consistency of this. I want to use `Promise.then` and then a `Promise.all` with the `Promise.then` on the result of `Promise.all` as examples in the language, obviously outside the web. But a thing that is caused often has multiple causes. -MM: And your observation is, there is always exactly one registration context clause. And there are some arbitrary number of dispatch clauses. So, for example, if you do a promise.all, on a number of promises, and then you do promise.then, a `promise.then` two clauses are the registration, and the settling of the promise you’re observing. So `promise.then` is a degenerate case of observing things and triggering the `promise.then` is a degenerate case of the logic of triggering an observer. Notifying an observer. +MM: And your observation is, there is always exactly one registration context clause. And there are some arbitrary number of dispatch clauses. So, for example, if you do a `Promise.all` on a number of promises, and then you do `Promise.then` and a `Promise.then`, the two clauses are the registration, and the settling of the promise you’re observing. So `Promise.then` is a degenerate case of observing things, and triggering the `Promise.then` is a degenerate case of the logic of triggering an observer, notifying an observer. -MM: By choosing the registration context, you’re not saying it’s more important and the others are less important. You are choosing a rule such that you always have a predictable model that the programmer can plan around, or programmer can coordinate on so that even when it’s not the one the programmer actually wants, they still know what it is and they can expect that it won’t be the one they want. And then you’ve provided these separate snapshots where the programmer knows they want something else and they can get. +MM: By choosing the registration context, you’re not saying it’s more important and the others are less important. You are choosing a rule such that you always have a predictable model that the programmer can plan around, or programmer can coordinate on so that even when it’s not the one the programmer actually wants, they still know what it is and they can expect that it won’t be the one they want. And then you’ve provided these separate snapshots where the programmer knows they want something else and they can get it. -MM: The issue—this goes to Shu’s question about, you know, it’s—to specific semantics of what is going on, it will differ from case to case about what the programmer wants. The real issue is not giving the programmer what they want in all cases. Implicitly, the issue is, if you provide other things explicitly less conveniently, the programmer can know when they need to turn and get the other one explicitly because that’s the one they really want. +MM: The issue—this goes to SYG’s question about the specific semantics of what is going on, it will differ from case to case about what the programmer wants. The real issue is not giving the programmer what they want in all cases implicitly. The issue is, if you provide one thing implicitly and other things explicitly, less conveniently, they have the one that’s implicitly provided be predictable. So the programmer can know when they need to turn and get the other one explicitly because that’s the one they really want. MM: Does that all make sense? I am asking SYG as well. Okay. -ABO: Yeah. That was part of the motivation for this initial proposal. But what we saw is that like some of the feedback that we got is that sometimes the implicit context is important because if you are a library, and the code that is like the code that in the listener is first party code, like the first party code would know to propagate those values. Would know to pass things around. And that—like, with this model, like, you only be made available to the third party code, the registration context. It seems like some use cases need that. We are investigating other solutions. And, like, so we’re looking at this problem and seeing how—if there is a way to propagate both things explicit in some case +ABO: Yeah. That was part of the motivation for this initial proposal. But what we saw is that like some of the feedback that we got is that sometimes the implicit context is important because if you are a third-party library, and the code in the listener is first-party code, the first-party code wouldn't know to propagate those values, wouldn't know to pass things around. And with this model, you would only be able to make available to the third party code the registration context. It seems like some use cases need that. We are investigating other solutions. And so we’re looking at this problem and seeing if there is a way to propagate both things implicitly in some way. -MM: I can’t propagate both things implicitly. In every case, there’s one thing to propagate because of the nature of the dynamic scoping you’re providing. +MM: You can’t propagate both things implicitly. In every case, there’s one thing to propagate because of the nature of the dynamic scoping you’re providing. MM: Well, okay. Justin suggested we talk in the hallway. I agreed. All right.