-
Notifications
You must be signed in to change notification settings - Fork 2.8k
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
Add a post-microtask-job list to event loops #2310
Conversation
Tests over in web-platform-tests/wpt#4643 |
Great, @smaug---- could you review the tests and this HTML Standard change? You're probably one of the few people that can... |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have a few naming concerns.
First, I think using "job" is not great here, because people might think it has to do with ES jobs. Maybe "steps" fits better with the rest of the spec, cf. "unloading document cleanup steps".
Second, I wonder if we want to give this a generic name and make it a generic hook, or just say "clean up IndexedDB transactions" and link out to an IDB algorithm. That would ensure nobody else uses this. We would then maybe generalize in the future if someone else needs it, but that seems pretty unlikely...
source
Outdated
@@ -88500,6 +88500,13 @@ dictionary <dfn>PromiseRejectionEventInit</dfn> : <span>EventInit</span> { | |||
source</span> used. Normally, the <span>task source</span> of a <span>microtask</span> is | |||
irrelevant.</p> | |||
|
|||
<p>Each <span>event loop</span> has a <dfn data-export="">post-microtask-job list</dfn>, which is | |||
« » initially. A post-microtask job cannot run scripts or be sensitive to when it is run relative |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd fairly strongly prefer "a list, initially empty".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was going to do that, but one of the things that annoys me about HTML is looking up the exact syntax to reference external concepts. And looking into fixing the tooling for HTML...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It should just be <span>list</span>
, right?
source
Outdated
to other post-microtask jobs. | ||
|
||
<p class="note">This is used by the Indexed Database API to deal with transactions. <ref | ||
spec=INDEXEDDB></p> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we add a warning that specs should not use this if at all possible, and please open an issue to discuss expanding its scope if so?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes we should do that.
source
Outdated
<li><p><i>Done</i>: For each <span>environment settings object</span> whose <span>responsible | ||
event loop</span> is this <span>event loop</span>, <span>notify about rejected promises</span> | ||
on that <span>environment settings object</span>.</p></li> | ||
<li> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think nesting is necessary here. Done is just a label you jump to; it can be attached to the single notify-about-rejected-promises step, and then execution will proceed to the post-microtask job business.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You mean modify the "notify about rejected promises" algorithm or modify the current Done step to do both things?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I mean just leave the current Done step (lines 88537-88539) as-is, then add a step after it, instead of creating a step named "done" with two substeps.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
r+ assuming the end-of-task isn't needed, and Domenic had good suggestions for naming.
source
Outdated
that <span>environment settings object</span>.</p></li> | ||
|
||
<li><p>Perform each post-microtask job in the <span>post-microtask-job list</span>.</p></li> | ||
</ol> | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok, this is not following the current model in Gecko's Promise handling, but I guess this is closer to Blink, right?. And that is fine I think.
In Gecko the callback is called after each Promise[1], not after handling all the Promises.
But as I said in w3c/IndexedDB#87 (comment) that feel a bit odd.
In Gecko the callback is also called around end-of-task, before any microtasks.
http://searchfox.org/mozilla-central/rev/b1aadb3572eaf7d2c70e19a2ba5413809d9ac698/xpcom/base/CycleCollectedJSContext.cpp#1400,1408
Is that needed by IDB? Can it have transactions open even outside microtasks and it would need to close those before running other microtask callbacks?
I hope that isn't needed, @inexorabletash ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As noted in w3c/IndexedDB#87 Blink and WebKit have a microtask checkpoint before the magic that deactivates transactions. (I think that would map in your cited code to moving the ProcessMetastableStateQueue
call after "step 4.1", but there's probably more subtlety.)
What's the behavior in Gecko when a microtask creates a transaction? i.e. if ProcessMetastableStateQueue is responsible for closing new stransactions, what if one is opened during PerformMicroTaskCheckpoint? When does that transaction get closed?
Can it have transactions open even outside microtasks and it would need to close those before running other microtask callbacks?
I think that's answered by the discussion in w3c/IndexedDB#87 which means I also think I'm misunderstanding the question. :( In Blink and WebKit, newly created transactions are active from the db.transaction()
call until after the task completes and a microtask checkpoint occurs. Previously created transactions are active from just before event dispatch until just after, which implicitly includes all of the event handlers/listeners and microtask checkpoints induced by that algorithm.
There should be no other time a transaction is active, e.g. where a timer's task could run and find a transaction is active. Similarly, I believe it's entirely deterministic whether a microtask gets handled in a particular task's subsequent microtask checkpoint or not; that is, there shouldn't be a case where a random task's microtask (e.g. a fetch's completion) is processed during an unrelated checkpoint (e.g. one where an unrelated transaction is active). But here we're hitting the limits of my knowledge so corrections/refinement appreciated.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think I'm asking can IDB have transactions open outside a microtask? Can something create/open a transaction when a script isn't running?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The only case where a transaction is not created by db.transaction()
is when the upgradeneeded
event is being dispatched. In that case the transaction starts off inactive, and is set active as part of the event dispatch, inactive when the dispatch is complete.
@inexorabletash if instead of "Perform each post-microtask job in the post-microtask-job list" we had "Cleanup Indexed Database transactions" which would be a term that the Indexed Database API defines, could that work well as a setup? That way this is not overly generic and cannot really be used by anyone else. |
We're okay with circular dependencies between specs I guess. IDB would still need to associate the "jobs" with the event loop in some way without monkey patching. Would defining that as a map event loop → list of transaction cleanup jobs in IDB be appropriate? And the "Cleanup Indexed Database transactions" would "pass" the event loop in? |
Yeah, we crossed that bridge long ago.
That sounds reasonable to me. Or we make the event loop available as "current event loop" or some such. Not sure what's better, but event loop is kinda a global variable. |
@domenic are you on board with the above plan? @smaug----? |
Yes |
Updated. Still need a URL from Indexed DB for the term. @inexorabletash I haven't passed event loop explicitly. You can get it from the current settings object easily enough. |
Sounds reasonable. |
Yeah, I'll try and get to a PR for IndexedDB this week for my end of the hook. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, will tag "do not merge yet" so we don't forget to update the href.
w3c/IndexedDB#145 is my first stab at the Indexed DB side of things. @smaug---- - can you take a look at the tests in web-platform-tests/wpt#4643 ? |
Landed tests in web-platform-tests/wpt@57aa2ac |
I've landed the Indexed DB change - the hook is now live: https://w3c.github.io/IndexedDB/#cleanup-indexed-database-transactions |
Fixes #2279.