-
Notifications
You must be signed in to change notification settings - Fork 316
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
async waitUntil microtask issue #1213
Comments
I'm OK with changing the test as I suspect you're right about the spec. Just not sure why we got it wrong in the first place. Did we all just read the spec wrong when discussing #1039 ? It's very hard for me to read the Service Worker spec and DOM spec and piece together what the expected behavior is.. easier to understand via WPT tests and examples. |
I also agree with changing the test. Thanks for spotting this @wanderview! |
Actually, now I'm confused again. I would think step 5 here would mean we throw since we should queue the microtask to decrement the number of pending promises: |
Olli suggests that the test should be saying "OK" there because the dispatch flag is set, I think: https://bugzilla.mozilla.org/show_bug.cgi?id=1409979#c4 Because we are running the test from an event handler. Would we throw InvalidStateError if we tried to do it from a setTimeout()? I'm not sure I understand why the dispatch flag matters here. |
Yes, setTimeout creates its own task, so the event isn't being dispatched during that time. |
I think the intent of checking the dispatch flag is to allow the initial |
I guess the setTimeout() case is already tested here: So I guess we can just mark this test case as returning OK: Maybe with a comment that its ok since the dispatching flag is set. If we really wanted to we could add a 3rd test case that adds a setTimeout() before the async_microtask_waituntil to show that it should fail if the dispatch flag is not set. |
Just a question: is the dispatch flag set whenever you are in a microtask "chained" to the original event dispatch? e.g., does this throw?
Similarly how about this one:
|
If more microtask stuff is added during a microtask checkpoint, they all are handled during that checkpoint. Microtasks are synchronous from browser point of view. |
I think the current test is what we settled on. I.e., it should throw in that case.
I think #1039 (comment) is the expected behavior we agreed. That is, we wanted to disallow a further lifetime extension in any async task when there's no holding extension promise.
I don't think the dispatch flag is set when the waitUntil is called in the microtask. The microtask checkpoint is performed after the event-dispatcher task is finished. |
No it isn't, except if there is some other JS on stack too (like, if the event is dispatched from JS). |
I thought if dispatch is invoked in a task, any microtasks queued in the task wouldn't be scheduled until the dispatch steps run to completion. Am I understanding it incorrectly? |
If there isn't any other script on stack, microtask checkpoint happens at the end of the each event listener call. So, if there are several listeners for an event, there will be several microtask checkpoints per event dispatch. |
I think those microtask checkpoints are preceded by the completion of the dispatch algorithm (where the dispatch flag's unset) regardless how many other tasks would be queued in the interim. |
No, the dispatch flag is unset after microtask checkpoints of event listeners are performed, according to https://dom.spec.whatwg.org/#dispatching-events:
|
I didn't realize the execution of each listener callback consumes the microtasks. That considered, I agree the WPT test (calling waitUntil() in a microtask) returns OK and doesn't throw an InvalidStateError. Thanks for the pointers. Sorry for my confusion. |
Reviewing the other cases again, I'm confused about the current-extension-expired-same-microtask-turn-extra case. Shouldn't it return OK because all the microtasks in the example will be consumed before the dispatch flag is unset? |
Per the spec language I think you are right. Looking at why our implementationdoesn't do that, we end up removing the "keep alive token" via a microtask: https://searchfox.org/mozilla-central/source/dom/workers/ServiceWorkerPrivate.cpp#386 This then means when the next WaitUntil() is called in a later microtask in the same dispatching task the "keep alive token" is gone. I was thinking maybe we could make it respect the dispatch flag here, but the "keep alive token" is created on another thread. It would be very difficult to do this in firefox. What would people think about adding another flag that says "extension promises were added and now all consumed"? If that flag is set, then we don't allow new extension promises to be added even if we are still dispatching the event. This might meet our original intent here? |
I think our spec wording is a little wrong here.
Fulfillment already queues a microtask, so we may be doing something redundant. Unless we're intentionally adding a microtask to a microtask, which I don't think we are. I'm struggling to get my head around this. I don't think this should work: const p = doSomething();
event.waitUntil(p);
p.then(() => event.waitUntil(doSomethingElse())); Because the pending promises count will be 0 when const p = doSomething();
p.then(() => event.waitUntil(doSomethingElse()));
event.waitUntil(p); …would work, since the I guess it's a bit of a gotcha, but it'll fail consistently. |
F2F: My comment above is wrong. The double microtask is intentional. The use of the dispatch flag is intentional and catches an edge case with multiple event listeners: addEventListener('fetch', event => {
event.waitUntil(Promise.resolve());
});
addEventListener('fetch', event => {
// This should work, and it's the dispatch flag that makes it work.
event.waitUntil(whatever());
}); Action: Review the tests for this. https://github.com/w3c/web-platform-tests/blob/a16738c524a65946b0ff7df6be37ae076ff5e860/service-workers/service-worker/resources/extendable-event-async-waituntil.js#L20 - waitUntil shouldn't throw here. |
Thanks for clarifying with the tests, @aliams. I think we mostly agree on the current spec behavior for
@wanderview, do you still have this issue or is it implementable? I thought of using event's extend lifetime promises for checking "extension promises were added" condition in your comment, but we still don't solve #1213 (comment) case without the dispatch flag. Having thought on it, (throwing when the dispatch flag is unset && count == 0) explains the desired behavior well I think. That is, the event is basically extendable during its own task turn and during when the extension opportunity isn't closed. Other than that, I'm a bit uncomfortable with the following cases. What do you think about them? const p = async_task_waituntil();
event.waitUntil(p);
p.then(() => { Promise.resolve().then(() => event.waitUntil(q)) }); // Throw. This throws since the count decrement microtask queued by waitUntil step 5 will run before the microtask queued by p.then callback. const p = async_task_waituntil();
p.then(() => { Promise.resolve().then(() => event.waitUntil(q)) }); // OK.
event.waitUntil(p); This runs OK since the count decrement microtask queued by waitUntil step 5 will run after the microtask queued by p.then callback. |
Is that to say that the test calling waitUntil in a different microtask without an existing extension should still throw. And that the test calling waitUntil at the end of the microtask turn still throws too? I believe due to the dispatch flag, these should actually be succeeding. |
@jungkees, are these what the tests would look like for what you are describing in your examples?
|
@aliams, yes, the tests look equivalent to the examples I gave above. I was talking about the cases where the promise (waitPromise in your example) resolves in an async task. The result of the waitUtil called in the extra microtask turn depends on whether the microtask for decrementing the pending lifetime promise count was called or not. The question was whether this would be expected behaviors? |
Sorry no that can't be right. p could take a long time and it doesn't make sense for the event dispatch flag to still be set in that case. I wonder if it matters that the test is using p = Promise.resolve() instead of a longer promise like one that resolves after setTimeout. |
To anyone interested, I have a patch with proposed test changes in https://chromium-review.googlesource.com/c/chromium/src/+/1524393. |
See discussion at [1] and [2]. This makes the following changes. 1. Adds a test for: self.addEventListener('fetch', e => { Promise.resolve().then(() => { e.respondWith(new Response('hi')); }); }); This should not throw because when respondWith() is called the event dispatch flag is still set. The microtask checkpoint is in "Cleanup After Running Scripts" here: https://html.spec.whatwg.org/multipage/webappapis.html#clean-up-after-running-script This is called from step 16.2 here: https://heycam.github.io/webidl/#call-a-user-objects-operation Which in turn is called from the DOM spec's "Inner Invoke" to call event targets: https://dom.spec.whatwg.org/#concept-event-listener-inner-invoke 2. Changes the expectation for: addEventListener('message', event => { Promise.resolve().then(event.waitUntil(p)); }); From throws to not throws, for the same reasoning as above. 3. Changes the expectation for: addEventListener('message', event => { waitPromise = Promise.resolve(); event.waitUntil(waitPromise); waitPromise.then(() => { Promise.resolve().then(() => {event.waitUntil();}); }); }); From throws to not throws. This is subtle. Because all the promises are just Promise.resolve(), the event dispatch flag is still set by the time the second waitUntil() is called. 4. To test what 3. originally intended, a new test is added which makes waitPromise a promise that does not immediately resolve. 5. Changes the expectation for: addEventListener(‘fetch’, event => { response = Promise.resolve(new Response('RESP')); event.respondWith(response); response.then(() => { Promise.resolve().then(() => {event.waitUntil();}); }) }); Again this is because the promises used resolve immediately, so the event dispatch flag is still set. Similarly, a new test is added to cover the original intent. These WPT changes appear to match the behavior of Safari and Edge while diverging from Chrome and (partially) Firefox. [1] w3c/ServiceWorker#1213 [2] w3c/ServiceWorker#1394 Bug: 942414 Change-Id: I9a4a56d71d3919ed614ff78df2bdc6cc0251dadd
See discussion at [1] and [2]. This makes the following changes. 1. Adds a test for: self.addEventListener('fetch', e => { Promise.resolve().then(() => { e.respondWith(new Response('hi')); }); }); This should not throw because when respondWith() is called the event dispatch flag is still set. The microtask checkpoint is in "Cleanup After Running Scripts" here: https://html.spec.whatwg.org/multipage/webappapis.html#clean-up-after-running-script This is called from step 16.2 here: https://heycam.github.io/webidl/#call-a-user-objects-operation Which in turn is called from the DOM spec's "Inner Invoke" to call event targets: https://dom.spec.whatwg.org/#concept-event-listener-inner-invoke 2. Changes the expectation for: addEventListener('message', event => { Promise.resolve().then(event.waitUntil(p)); }); From throws to not throws, for the same reasoning as above. 3. Changes the expectation for: addEventListener('message', event => { waitPromise = Promise.resolve(); event.waitUntil(waitPromise); waitPromise.then(() => { Promise.resolve().then(() => {event.waitUntil();}); }); }); From throws to not throws. This is subtle. Because all the promises are just Promise.resolve(), the event dispatch flag is still set by the time the second waitUntil() is called. 4. To test what 3. originally intended, a new test is added which makes waitPromise a promise that does not immediately resolve. 5. Changes the expectation for: addEventListener(‘fetch’, event => { response = Promise.resolve(new Response('RESP')); event.respondWith(response); response.then(() => { Promise.resolve().then(() => {event.waitUntil();}); }) }); Again this is because the promises used resolve immediately, so the event dispatch flag is still set. Similarly, a new test is added to cover the original intent. These WPT changes appear to match the behavior of Safari and Edge while diverging from Chrome and (partially) Firefox. [1] w3c/ServiceWorker#1213 [2] w3c/ServiceWorker#1394 Bug: 942414 Change-Id: I9a4a56d71d3919ed614ff78df2bdc6cc0251dadd
FWIW, I think this analysis here is correct and your test looks good. Thanks! |
As far as I know you cannot trigger this situation in other ways (except via similar promise APIs that have near-identical semantics, if those exist). Certainly not with |
I think in theory something like a |
Thanks for the clarification and the test changes! I think the initially referenced Firefox bug https://bugzilla.mozilla.org/show_bug.cgi?id=1409979 and the failures in that WPT PR for Firefox are now just about Firefox's ExtendableEvent.waitUntil() failing to check the dispatch flag. |
@wanderview no, that should at the very least queue a task from the fetch layer. |
See discussion at [1] and [2]. This makes the following changes. 1. Adds a test for: self.addEventListener('fetch', e => { Promise.resolve().then(() => { e.respondWith(new Response('hi')); }); }); This should not throw because when respondWith() is called while the event dispatch flag is still set. The microtask checkpoint is in "Cleanup After Running Scripts" here: https://html.spec.whatwg.org/multipage/webappapis.html#clean-up-after-running-script This is called from step 16.2 here: https://heycam.github.io/webidl/#call-a-user-objects-operation Which in turn is called from the DOM spec's "Inner Invoke" to call event targets: https://dom.spec.whatwg.org/#concept-event-listener-inner-invoke 2. Changes the expectation for: addEventListener('message', event => { Promise.resolve().then(event.waitUntil(p)); }); From throws to not throws, for the same reasoning as above. 3. Changes the expectation for: addEventListener('message', event => { waitPromise = Promise.resolve(); event.waitUntil(waitPromise); waitPromise.then(() => { Promise.resolve().then(() => {event.waitUntil();}); }); }); From throws to not throws. This is subtle. Because all the promises are just Promise.resolve(), the event dispatch flag is still set by the time the second waitUntil() is called. 4. To test what 3. originally intended, a new test is added which makes waitPromise a promise that does not immediately resolve. 5. Changes the expectation for: addEventListener(‘fetch’, event => { response = Promise.resolve(new Response('RESP')); event.respondWith(response); response.then(() => { Promise.resolve().then(() => {event.waitUntil();}); }) }); Again this is because the promises used resolve immediately, so the event dispatch flag is still set. Similarly, a new test is added to cover the original intent. These WPT changes appear to match the behavior of Safari and Edge while diverging from Chrome and (partially) Firefox. [1] w3c/ServiceWorker#1213 [2] w3c/ServiceWorker#1394 Bug: 942414 Change-Id: I9a4a56d71d3919ed614ff78df2bdc6cc0251dadd
See discussion at [1] and [2]. This makes the following changes. 1. Adds a test for: self.addEventListener('fetch', e => { Promise.resolve().then(() => { e.respondWith(new Response('hi')); }); }); This should not throw because when respondWith() is called while the event dispatch flag is still set. The microtask checkpoint is in "Cleanup After Running Scripts" here: https://html.spec.whatwg.org/multipage/webappapis.html#clean-up-after-running-script This is called from step 16.2 here: https://heycam.github.io/webidl/#call-a-user-objects-operation Which in turn is called from the DOM spec's "Inner Invoke" to call event targets: https://dom.spec.whatwg.org/#concept-event-listener-inner-invoke 2. Changes the expectation for: addEventListener('message', event => { Promise.resolve().then(event.waitUntil(p)); }); From throws to not throws, for the same reasoning as above. 3. Changes the expectation for: addEventListener('message', event => { waitPromise = Promise.resolve(); event.waitUntil(waitPromise); waitPromise.then(() => { Promise.resolve().then(() => {event.waitUntil();}); }); }); From throws to not throws. This is subtle. Because all the promises are just Promise.resolve(), the event dispatch flag is still set by the time the second waitUntil() is called. 4. To test what 3. originally intended, a new test is added which makes waitPromise a promise that does not immediately resolve. 5. Changes the expectation for: addEventListener(‘fetch’, event => { response = Promise.resolve(new Response('RESP')); event.respondWith(response); response.then(() => { Promise.resolve().then(() => {event.waitUntil();}); }) }); Again this is because the promises used resolve immediately, so the event dispatch flag is still set. Similarly, a new test is added to cover the original intent. These WPT changes appear to match the behavior of Safari and Edge while diverging from Chrome and (partially) Firefox. [1] w3c/ServiceWorker#1213 [2] w3c/ServiceWorker#1394 Bug: 942414 Change-Id: I9a4a56d71d3919ed614ff78df2bdc6cc0251dadd
See discussion at [1] and [2]. This makes the following changes. 1. Adds a test for: self.addEventListener('fetch', e => { Promise.resolve().then(() => { e.respondWith(new Response('hi')); }); }); This should not throw because respondWith() is called while the event dispatch flag is still set. The microtask checkpoint is in "Cleanup After Running Scripts" here: https://html.spec.whatwg.org/multipage/webappapis.html#clean-up-after-running-script This is called from step 16.2 here: https://heycam.github.io/webidl/#call-a-user-objects-operation Which in turn is called from the DOM spec's "Inner Invoke" to call event targets: https://dom.spec.whatwg.org/#concept-event-listener-inner-invoke 2. Changes the expectation for: addEventListener('message', event => { Promise.resolve().then(event.waitUntil(p)); }); From throws to not throws, for the same reasoning as above. 3. Changes the expectation for: addEventListener('message', event => { waitPromise = Promise.resolve(); event.waitUntil(waitPromise); waitPromise.then(() => { Promise.resolve().then(() => {event.waitUntil();}); }); }); From throws to not throws. This is subtle. Because all the promises are just Promise.resolve(), the event dispatch flag is still set by the time the second waitUntil() is called. 4. To test what 3. originally intended, a new test is added which makes waitPromise a promise that does not immediately resolve. 5. Changes the expectation for: addEventListener(‘fetch’, event => { response = Promise.resolve(new Response('RESP')); event.respondWith(response); response.then(() => { Promise.resolve().then(() => {event.waitUntil();}); }) }); Again this is because the promises used resolve immediately, so the event dispatch flag is still set. Similarly, a new test is added to cover the original intent. These WPT changes appear to match the behavior of Safari and Edge while diverging from Chrome and (partially) Firefox. [1] w3c/ServiceWorker#1213 [2] w3c/ServiceWorker#1394 Bug: 942414 Change-Id: I9a4a56d71d3919ed614ff78df2bdc6cc0251dadd
See discussion at [1] and [2]. This makes the following changes. 1. Adds a test for: self.addEventListener('fetch', e => { Promise.resolve().then(() => { e.respondWith(new Response('hi')); }); }); This should not throw because respondWith() is called while the event dispatch flag is still set. The microtask checkpoint is in "Cleanup After Running Scripts" here: https://html.spec.whatwg.org/multipage/webappapis.html#clean-up-after-running-script This is called from step 16.2 here: https://heycam.github.io/webidl/#call-a-user-objects-operation Which in turn is called from the DOM spec's "Inner Invoke" to call event targets: https://dom.spec.whatwg.org/#concept-event-listener-inner-invoke 2. Changes the expectation for: addEventListener('message', event => { Promise.resolve().then(event.waitUntil(p)); }); From throws to not throws, for the same reasoning as above. 3. Changes the expectation for: addEventListener('message', event => { waitPromise = Promise.resolve(); event.waitUntil(waitPromise); waitPromise.then(() => { Promise.resolve().then(() => {event.waitUntil();}); }); }); From throws to not throws. This is subtle. Because all the promises are just Promise.resolve(), the event dispatch flag is still set by the time the second waitUntil() is called. 4. To test what 3. originally intended, a new test is added which makes waitPromise a promise that does not immediately resolve. 5. Changes the expectation for: addEventListener(‘fetch’, event => { response = Promise.resolve(new Response('RESP')); event.respondWith(response); response.then(() => { Promise.resolve().then(() => {event.waitUntil();}); }) }); Again this is because the promises used resolve immediately, so the event dispatch flag is still set. Similarly, a new test is added to cover the original intent. These WPT changes appear to match the behavior of Safari and Edge while diverging from Chrome and (partially) Firefox. [1] w3c/ServiceWorker#1213 [2] w3c/ServiceWorker#1394 Bug: 942414 Change-Id: I9a4a56d71d3919ed614ff78df2bdc6cc0251dadd Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1524393 Commit-Queue: Matt Falkenhagen <falken@chromium.org> Reviewed-by: Ben Kelly <wanderview@chromium.org> Cr-Commit-Position: refs/heads/master@{#641514}
See discussion at [1] and [2]. This makes the following changes. 1. Adds a test for: self.addEventListener('fetch', e => { Promise.resolve().then(() => { e.respondWith(new Response('hi')); }); }); This should not throw because respondWith() is called while the event dispatch flag is still set. The microtask checkpoint is in "Cleanup After Running Scripts" here: https://html.spec.whatwg.org/multipage/webappapis.html#clean-up-after-running-script This is called from step 16.2 here: https://heycam.github.io/webidl/#call-a-user-objects-operation Which in turn is called from the DOM spec's "Inner Invoke" to call event targets: https://dom.spec.whatwg.org/#concept-event-listener-inner-invoke 2. Changes the expectation for: addEventListener('message', event => { Promise.resolve().then(event.waitUntil(p)); }); From throws to not throws, for the same reasoning as above. 3. Changes the expectation for: addEventListener('message', event => { waitPromise = Promise.resolve(); event.waitUntil(waitPromise); waitPromise.then(() => { Promise.resolve().then(() => {event.waitUntil();}); }); }); From throws to not throws. This is subtle. Because all the promises are just Promise.resolve(), the event dispatch flag is still set by the time the second waitUntil() is called. 4. To test what 3. originally intended, a new test is added which makes waitPromise a promise that does not immediately resolve. 5. Changes the expectation for: addEventListener(‘fetch’, event => { response = Promise.resolve(new Response('RESP')); event.respondWith(response); response.then(() => { Promise.resolve().then(() => {event.waitUntil();}); }) }); Again this is because the promises used resolve immediately, so the event dispatch flag is still set. Similarly, a new test is added to cover the original intent. These WPT changes appear to match the behavior of Safari and Edge while diverging from Chrome and (partially) Firefox. [1] w3c/ServiceWorker#1213 [2] w3c/ServiceWorker#1394 Bug: 942414 Change-Id: I9a4a56d71d3919ed614ff78df2bdc6cc0251dadd Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1524393 Commit-Queue: Matt Falkenhagen <falken@chromium.org> Reviewed-by: Ben Kelly <wanderview@chromium.org> Cr-Commit-Position: refs/heads/master@{#641514}
…15852) See discussion at [1] and [2]. This makes the following changes. 1. Adds a test for: self.addEventListener('fetch', e => { Promise.resolve().then(() => { e.respondWith(new Response('hi')); }); }); This should not throw because respondWith() is called while the event dispatch flag is still set. The microtask checkpoint is in "Cleanup After Running Scripts" here: https://html.spec.whatwg.org/multipage/webappapis.html#clean-up-after-running-script This is called from step 16.2 here: https://heycam.github.io/webidl/#call-a-user-objects-operation Which in turn is called from the DOM spec's "Inner Invoke" to call event targets: https://dom.spec.whatwg.org/#concept-event-listener-inner-invoke 2. Changes the expectation for: addEventListener('message', event => { Promise.resolve().then(event.waitUntil(p)); }); From throws to not throws, for the same reasoning as above. 3. Changes the expectation for: addEventListener('message', event => { waitPromise = Promise.resolve(); event.waitUntil(waitPromise); waitPromise.then(() => { Promise.resolve().then(() => {event.waitUntil();}); }); }); From throws to not throws. This is subtle. Because all the promises are just Promise.resolve(), the event dispatch flag is still set by the time the second waitUntil() is called. 4. To test what 3. originally intended, a new test is added which makes waitPromise a promise that does not immediately resolve. 5. Changes the expectation for: addEventListener(‘fetch’, event => { response = Promise.resolve(new Response('RESP')); event.respondWith(response); response.then(() => { Promise.resolve().then(() => {event.waitUntil();}); }) }); Again this is because the promises used resolve immediately, so the event dispatch flag is still set. Similarly, a new test is added to cover the original intent. These WPT changes appear to match the behavior of Safari and Edge while diverging from Chrome and (partially) Firefox. [1] w3c/ServiceWorker#1213 [2] w3c/ServiceWorker#1394 Bug: 942414 Change-Id: I9a4a56d71d3919ed614ff78df2bdc6cc0251dadd Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1524393 Commit-Queue: Matt Falkenhagen <falken@chromium.org> Reviewed-by: Ben Kelly <wanderview@chromium.org> Cr-Commit-Position: refs/heads/master@{#641514}
Thanks all! the WPT tests have been updated. The tricky part was indeed that some tests were using Promise.resolve() which meant the event dispatch flag was still set when the test intended to test the pending promises count instead. I've added test cases for those now. I think we can now close this. |
…ync respondWith/waitUntil., a=testonly Automatic update from web-platform-tests service worker: Improve WPT tests for async respondWith/waitUntil. (#15852) See discussion at [1] and [2]. This makes the following changes. 1. Adds a test for: self.addEventListener('fetch', e => { Promise.resolve().then(() => { e.respondWith(new Response('hi')); }); }); This should not throw because respondWith() is called while the event dispatch flag is still set. The microtask checkpoint is in "Cleanup After Running Scripts" here: https://html.spec.whatwg.org/multipage/webappapis.html#clean-up-after-running-script This is called from step 16.2 here: https://heycam.github.io/webidl/#call-a-user-objects-operation Which in turn is called from the DOM spec's "Inner Invoke" to call event targets: https://dom.spec.whatwg.org/#concept-event-listener-inner-invoke 2. Changes the expectation for: addEventListener('message', event => { Promise.resolve().then(event.waitUntil(p)); }); From throws to not throws, for the same reasoning as above. 3. Changes the expectation for: addEventListener('message', event => { waitPromise = Promise.resolve(); event.waitUntil(waitPromise); waitPromise.then(() => { Promise.resolve().then(() => {event.waitUntil();}); }); }); From throws to not throws. This is subtle. Because all the promises are just Promise.resolve(), the event dispatch flag is still set by the time the second waitUntil() is called. 4. To test what 3. originally intended, a new test is added which makes waitPromise a promise that does not immediately resolve. 5. Changes the expectation for: addEventListener(‘fetch’, event => { response = Promise.resolve(new Response('RESP')); event.respondWith(response); response.then(() => { Promise.resolve().then(() => {event.waitUntil();}); }) }); Again this is because the promises used resolve immediately, so the event dispatch flag is still set. Similarly, a new test is added to cover the original intent. These WPT changes appear to match the behavior of Safari and Edge while diverging from Chrome and (partially) Firefox. [1] w3c/ServiceWorker#1213 [2] w3c/ServiceWorker#1394 Bug: 942414 Change-Id: I9a4a56d71d3919ed614ff78df2bdc6cc0251dadd Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1524393 Commit-Queue: Matt Falkenhagen <falken@chromium.org> Reviewed-by: Ben Kelly <wanderview@chromium.org> Cr-Commit-Position: refs/heads/master@{#641514} -- wpt-commits: cecb3eba4dae3d795876f7b4be71bd49afa03356 wpt-pr: 15852
…ync respondWith/waitUntil., a=testonly Automatic update from web-platform-tests service worker: Improve WPT tests for async respondWith/waitUntil. (#15852) See discussion at [1] and [2]. This makes the following changes. 1. Adds a test for: self.addEventListener('fetch', e => { Promise.resolve().then(() => { e.respondWith(new Response('hi')); }); }); This should not throw because respondWith() is called while the event dispatch flag is still set. The microtask checkpoint is in "Cleanup After Running Scripts" here: https://html.spec.whatwg.org/multipage/webappapis.html#clean-up-after-running-script This is called from step 16.2 here: https://heycam.github.io/webidl/#call-a-user-objects-operation Which in turn is called from the DOM spec's "Inner Invoke" to call event targets: https://dom.spec.whatwg.org/#concept-event-listener-inner-invoke 2. Changes the expectation for: addEventListener('message', event => { Promise.resolve().then(event.waitUntil(p)); }); From throws to not throws, for the same reasoning as above. 3. Changes the expectation for: addEventListener('message', event => { waitPromise = Promise.resolve(); event.waitUntil(waitPromise); waitPromise.then(() => { Promise.resolve().then(() => {event.waitUntil();}); }); }); From throws to not throws. This is subtle. Because all the promises are just Promise.resolve(), the event dispatch flag is still set by the time the second waitUntil() is called. 4. To test what 3. originally intended, a new test is added which makes waitPromise a promise that does not immediately resolve. 5. Changes the expectation for: addEventListener(‘fetch’, event => { response = Promise.resolve(new Response('RESP')); event.respondWith(response); response.then(() => { Promise.resolve().then(() => {event.waitUntil();}); }) }); Again this is because the promises used resolve immediately, so the event dispatch flag is still set. Similarly, a new test is added to cover the original intent. These WPT changes appear to match the behavior of Safari and Edge while diverging from Chrome and (partially) Firefox. [1] w3c/ServiceWorker#1213 [2] w3c/ServiceWorker#1394 Bug: 942414 Change-Id: I9a4a56d71d3919ed614ff78df2bdc6cc0251dadd Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1524393 Commit-Queue: Matt Falkenhagen <falken@chromium.org> Reviewed-by: Ben Kelly <wanderview@chromium.org> Cr-Commit-Position: refs/heads/master@{#641514} -- wpt-commits: cecb3eba4dae3d795876f7b4be71bd49afa03356 wpt-pr: 15852
…ync respondWith/waitUntil., a=testonly Automatic update from web-platform-tests service worker: Improve WPT tests for async respondWith/waitUntil. (#15852) See discussion at [1] and [2]. This makes the following changes. 1. Adds a test for: self.addEventListener('fetch', e => { Promise.resolve().then(() => { e.respondWith(new Response('hi')); }); }); This should not throw because respondWith() is called while the event dispatch flag is still set. The microtask checkpoint is in "Cleanup After Running Scripts" here: https://html.spec.whatwg.org/multipage/webappapis.html#clean-up-after-running-script This is called from step 16.2 here: https://heycam.github.io/webidl/#call-a-user-objects-operation Which in turn is called from the DOM spec's "Inner Invoke" to call event targets: https://dom.spec.whatwg.org/#concept-event-listener-inner-invoke 2. Changes the expectation for: addEventListener('message', event => { Promise.resolve().then(event.waitUntil(p)); }); From throws to not throws, for the same reasoning as above. 3. Changes the expectation for: addEventListener('message', event => { waitPromise = Promise.resolve(); event.waitUntil(waitPromise); waitPromise.then(() => { Promise.resolve().then(() => {event.waitUntil();}); }); }); From throws to not throws. This is subtle. Because all the promises are just Promise.resolve(), the event dispatch flag is still set by the time the second waitUntil() is called. 4. To test what 3. originally intended, a new test is added which makes waitPromise a promise that does not immediately resolve. 5. Changes the expectation for: addEventListener(‘fetch’, event => { response = Promise.resolve(new Response('RESP')); event.respondWith(response); response.then(() => { Promise.resolve().then(() => {event.waitUntil();}); }) }); Again this is because the promises used resolve immediately, so the event dispatch flag is still set. Similarly, a new test is added to cover the original intent. These WPT changes appear to match the behavior of Safari and Edge while diverging from Chrome and (partially) Firefox. [1] w3c/ServiceWorker#1213 [2] w3c/ServiceWorker#1394 Bug: 942414 Change-Id: I9a4a56d71d3919ed614ff78df2bdc6cc0251dadd Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1524393 Commit-Queue: Matt Falkenhagen <falken@chromium.org> Reviewed-by: Ben Kelly <wanderview@chromium.org> Cr-Commit-Position: refs/heads/master@{#641514} -- wpt-commits: cecb3eba4dae3d795876f7b4be71bd49afa03356 wpt-pr: 15852
…ync respondWith/waitUntil., a=testonly Automatic update from web-platform-tests service worker: Improve WPT tests for async respondWith/waitUntil. (#15852) See discussion at [1] and [2]. This makes the following changes. 1. Adds a test for: self.addEventListener('fetch', e => { Promise.resolve().then(() => { e.respondWith(new Response('hi')); }); }); This should not throw because respondWith() is called while the event dispatch flag is still set. The microtask checkpoint is in "Cleanup After Running Scripts" here: https://html.spec.whatwg.org/multipage/webappapis.html#clean-up-after-running-script This is called from step 16.2 here: https://heycam.github.io/webidl/#call-a-user-objects-operation Which in turn is called from the DOM spec's "Inner Invoke" to call event targets: https://dom.spec.whatwg.org/#concept-event-listener-inner-invoke 2. Changes the expectation for: addEventListener('message', event => { Promise.resolve().then(event.waitUntil(p)); }); From throws to not throws, for the same reasoning as above. 3. Changes the expectation for: addEventListener('message', event => { waitPromise = Promise.resolve(); event.waitUntil(waitPromise); waitPromise.then(() => { Promise.resolve().then(() => {event.waitUntil();}); }); }); From throws to not throws. This is subtle. Because all the promises are just Promise.resolve(), the event dispatch flag is still set by the time the second waitUntil() is called. 4. To test what 3. originally intended, a new test is added which makes waitPromise a promise that does not immediately resolve. 5. Changes the expectation for: addEventListener(‘fetch’, event => { response = Promise.resolve(new Response('RESP')); event.respondWith(response); response.then(() => { Promise.resolve().then(() => {event.waitUntil();}); }) }); Again this is because the promises used resolve immediately, so the event dispatch flag is still set. Similarly, a new test is added to cover the original intent. These WPT changes appear to match the behavior of Safari and Edge while diverging from Chrome and (partially) Firefox. [1] w3c/ServiceWorker#1213 [2] w3c/ServiceWorker#1394 Bug: 942414 Change-Id: I9a4a56d71d3919ed614ff78df2bdc6cc0251dadd Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1524393 Commit-Queue: Matt Falkenhagen <falken@chromium.org> Reviewed-by: Ben Kelly <wanderview@chromium.org> Cr-Commit-Position: refs/heads/master@{#641514} -- wpt-commits: cecb3eba4dae3d795876f7b4be71bd49afa03356 wpt-pr: 15852
…15852) See discussion at [1] and [2]. This makes the following changes. 1. Adds a test for: self.addEventListener('fetch', e => { Promise.resolve().then(() => { e.respondWith(new Response('hi')); }); }); This should not throw because respondWith() is called while the event dispatch flag is still set. The microtask checkpoint is in "Cleanup After Running Scripts" here: https://html.spec.whatwg.org/multipage/webappapis.html#clean-up-after-running-script This is called from step 16.2 here: https://heycam.github.io/webidl/#call-a-user-objects-operation Which in turn is called from the DOM spec's "Inner Invoke" to call event targets: https://dom.spec.whatwg.org/#concept-event-listener-inner-invoke 2. Changes the expectation for: addEventListener('message', event => { Promise.resolve().then(event.waitUntil(p)); }); From throws to not throws, for the same reasoning as above. 3. Changes the expectation for: addEventListener('message', event => { waitPromise = Promise.resolve(); event.waitUntil(waitPromise); waitPromise.then(() => { Promise.resolve().then(() => {event.waitUntil();}); }); }); From throws to not throws. This is subtle. Because all the promises are just Promise.resolve(), the event dispatch flag is still set by the time the second waitUntil() is called. 4. To test what 3. originally intended, a new test is added which makes waitPromise a promise that does not immediately resolve. 5. Changes the expectation for: addEventListener(‘fetch’, event => { response = Promise.resolve(new Response('RESP')); event.respondWith(response); response.then(() => { Promise.resolve().then(() => {event.waitUntil();}); }) }); Again this is because the promises used resolve immediately, so the event dispatch flag is still set. Similarly, a new test is added to cover the original intent. These WPT changes appear to match the behavior of Safari and Edge while diverging from Chrome and (partially) Firefox. [1] w3c/ServiceWorker#1213 [2] w3c/ServiceWorker#1394 Bug: 942414 Change-Id: I9a4a56d71d3919ed614ff78df2bdc6cc0251dadd Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1524393 Commit-Queue: Matt Falkenhagen <falken@chromium.org> Reviewed-by: Ben Kelly <wanderview@chromium.org> Cr-Commit-Position: refs/heads/master@{#641514}
…ync respondWith/waitUntil., a=testonly Automatic update from web-platform-tests service worker: Improve WPT tests for async respondWith/waitUntil. (#15852) See discussion at [1] and [2]. This makes the following changes. 1. Adds a test for: self.addEventListener('fetch', e => { Promise.resolve().then(() => { e.respondWith(new Response('hi')); }); }); This should not throw because respondWith() is called while the event dispatch flag is still set. The microtask checkpoint is in "Cleanup After Running Scripts" here: https://html.spec.whatwg.org/multipage/webappapis.html#clean-up-after-running-script This is called from step 16.2 here: https://heycam.github.io/webidl/#call-a-user-objects-operation Which in turn is called from the DOM spec's "Inner Invoke" to call event targets: https://dom.spec.whatwg.org/#concept-event-listener-inner-invoke 2. Changes the expectation for: addEventListener('message', event => { Promise.resolve().then(event.waitUntil(p)); }); From throws to not throws, for the same reasoning as above. 3. Changes the expectation for: addEventListener('message', event => { waitPromise = Promise.resolve(); event.waitUntil(waitPromise); waitPromise.then(() => { Promise.resolve().then(() => {event.waitUntil();}); }); }); From throws to not throws. This is subtle. Because all the promises are just Promise.resolve(), the event dispatch flag is still set by the time the second waitUntil() is called. 4. To test what 3. originally intended, a new test is added which makes waitPromise a promise that does not immediately resolve. 5. Changes the expectation for: addEventListener(‘fetch’, event => { response = Promise.resolve(new Response('RESP')); event.respondWith(response); response.then(() => { Promise.resolve().then(() => {event.waitUntil();}); }) }); Again this is because the promises used resolve immediately, so the event dispatch flag is still set. Similarly, a new test is added to cover the original intent. These WPT changes appear to match the behavior of Safari and Edge while diverging from Chrome and (partially) Firefox. [1] w3c/ServiceWorker#1213 [2] w3c/ServiceWorker#1394 Bug: 942414 Change-Id: I9a4a56d71d3919ed614ff78df2bdc6cc0251dadd Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1524393 Commit-Queue: Matt Falkenhagen <falkenchromium.org> Reviewed-by: Ben Kelly <wanderviewchromium.org> Cr-Commit-Position: refs/heads/master{#641514} -- wpt-commits: cecb3eba4dae3d795876f7b4be71bd49afa03356 wpt-pr: 15852 UltraBlame original commit: a941738d800eb075978e20b17f3a72cb680a8398
…ync respondWith/waitUntil., a=testonly Automatic update from web-platform-tests service worker: Improve WPT tests for async respondWith/waitUntil. (#15852) See discussion at [1] and [2]. This makes the following changes. 1. Adds a test for: self.addEventListener('fetch', e => { Promise.resolve().then(() => { e.respondWith(new Response('hi')); }); }); This should not throw because respondWith() is called while the event dispatch flag is still set. The microtask checkpoint is in "Cleanup After Running Scripts" here: https://html.spec.whatwg.org/multipage/webappapis.html#clean-up-after-running-script This is called from step 16.2 here: https://heycam.github.io/webidl/#call-a-user-objects-operation Which in turn is called from the DOM spec's "Inner Invoke" to call event targets: https://dom.spec.whatwg.org/#concept-event-listener-inner-invoke 2. Changes the expectation for: addEventListener('message', event => { Promise.resolve().then(event.waitUntil(p)); }); From throws to not throws, for the same reasoning as above. 3. Changes the expectation for: addEventListener('message', event => { waitPromise = Promise.resolve(); event.waitUntil(waitPromise); waitPromise.then(() => { Promise.resolve().then(() => {event.waitUntil();}); }); }); From throws to not throws. This is subtle. Because all the promises are just Promise.resolve(), the event dispatch flag is still set by the time the second waitUntil() is called. 4. To test what 3. originally intended, a new test is added which makes waitPromise a promise that does not immediately resolve. 5. Changes the expectation for: addEventListener(‘fetch’, event => { response = Promise.resolve(new Response('RESP')); event.respondWith(response); response.then(() => { Promise.resolve().then(() => {event.waitUntil();}); }) }); Again this is because the promises used resolve immediately, so the event dispatch flag is still set. Similarly, a new test is added to cover the original intent. These WPT changes appear to match the behavior of Safari and Edge while diverging from Chrome and (partially) Firefox. [1] w3c/ServiceWorker#1213 [2] w3c/ServiceWorker#1394 Bug: 942414 Change-Id: I9a4a56d71d3919ed614ff78df2bdc6cc0251dadd Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1524393 Commit-Queue: Matt Falkenhagen <falkenchromium.org> Reviewed-by: Ben Kelly <wanderviewchromium.org> Cr-Commit-Position: refs/heads/master{#641514} -- wpt-commits: cecb3eba4dae3d795876f7b4be71bd49afa03356 wpt-pr: 15852 UltraBlame original commit: b4b704c52ae96a9cdfbc3c4565a39d17f2480d19
…ync respondWith/waitUntil., a=testonly Automatic update from web-platform-tests service worker: Improve WPT tests for async respondWith/waitUntil. (#15852) See discussion at [1] and [2]. This makes the following changes. 1. Adds a test for: self.addEventListener('fetch', e => { Promise.resolve().then(() => { e.respondWith(new Response('hi')); }); }); This should not throw because respondWith() is called while the event dispatch flag is still set. The microtask checkpoint is in "Cleanup After Running Scripts" here: https://html.spec.whatwg.org/multipage/webappapis.html#clean-up-after-running-script This is called from step 16.2 here: https://heycam.github.io/webidl/#call-a-user-objects-operation Which in turn is called from the DOM spec's "Inner Invoke" to call event targets: https://dom.spec.whatwg.org/#concept-event-listener-inner-invoke 2. Changes the expectation for: addEventListener('message', event => { Promise.resolve().then(event.waitUntil(p)); }); From throws to not throws, for the same reasoning as above. 3. Changes the expectation for: addEventListener('message', event => { waitPromise = Promise.resolve(); event.waitUntil(waitPromise); waitPromise.then(() => { Promise.resolve().then(() => {event.waitUntil();}); }); }); From throws to not throws. This is subtle. Because all the promises are just Promise.resolve(), the event dispatch flag is still set by the time the second waitUntil() is called. 4. To test what 3. originally intended, a new test is added which makes waitPromise a promise that does not immediately resolve. 5. Changes the expectation for: addEventListener(‘fetch’, event => { response = Promise.resolve(new Response('RESP')); event.respondWith(response); response.then(() => { Promise.resolve().then(() => {event.waitUntil();}); }) }); Again this is because the promises used resolve immediately, so the event dispatch flag is still set. Similarly, a new test is added to cover the original intent. These WPT changes appear to match the behavior of Safari and Edge while diverging from Chrome and (partially) Firefox. [1] w3c/ServiceWorker#1213 [2] w3c/ServiceWorker#1394 Bug: 942414 Change-Id: I9a4a56d71d3919ed614ff78df2bdc6cc0251dadd Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1524393 Commit-Queue: Matt Falkenhagen <falkenchromium.org> Reviewed-by: Ben Kelly <wanderviewchromium.org> Cr-Commit-Position: refs/heads/master{#641514} -- wpt-commits: cecb3eba4dae3d795876f7b4be71bd49afa03356 wpt-pr: 15852 UltraBlame original commit: a941738d800eb075978e20b17f3a72cb680a8398
…ync respondWith/waitUntil., a=testonly Automatic update from web-platform-tests service worker: Improve WPT tests for async respondWith/waitUntil. (#15852) See discussion at [1] and [2]. This makes the following changes. 1. Adds a test for: self.addEventListener('fetch', e => { Promise.resolve().then(() => { e.respondWith(new Response('hi')); }); }); This should not throw because respondWith() is called while the event dispatch flag is still set. The microtask checkpoint is in "Cleanup After Running Scripts" here: https://html.spec.whatwg.org/multipage/webappapis.html#clean-up-after-running-script This is called from step 16.2 here: https://heycam.github.io/webidl/#call-a-user-objects-operation Which in turn is called from the DOM spec's "Inner Invoke" to call event targets: https://dom.spec.whatwg.org/#concept-event-listener-inner-invoke 2. Changes the expectation for: addEventListener('message', event => { Promise.resolve().then(event.waitUntil(p)); }); From throws to not throws, for the same reasoning as above. 3. Changes the expectation for: addEventListener('message', event => { waitPromise = Promise.resolve(); event.waitUntil(waitPromise); waitPromise.then(() => { Promise.resolve().then(() => {event.waitUntil();}); }); }); From throws to not throws. This is subtle. Because all the promises are just Promise.resolve(), the event dispatch flag is still set by the time the second waitUntil() is called. 4. To test what 3. originally intended, a new test is added which makes waitPromise a promise that does not immediately resolve. 5. Changes the expectation for: addEventListener(‘fetch’, event => { response = Promise.resolve(new Response('RESP')); event.respondWith(response); response.then(() => { Promise.resolve().then(() => {event.waitUntil();}); }) }); Again this is because the promises used resolve immediately, so the event dispatch flag is still set. Similarly, a new test is added to cover the original intent. These WPT changes appear to match the behavior of Safari and Edge while diverging from Chrome and (partially) Firefox. [1] w3c/ServiceWorker#1213 [2] w3c/ServiceWorker#1394 Bug: 942414 Change-Id: I9a4a56d71d3919ed614ff78df2bdc6cc0251dadd Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1524393 Commit-Queue: Matt Falkenhagen <falkenchromium.org> Reviewed-by: Ben Kelly <wanderviewchromium.org> Cr-Commit-Position: refs/heads/master{#641514} -- wpt-commits: cecb3eba4dae3d795876f7b4be71bd49afa03356 wpt-pr: 15852 UltraBlame original commit: b4b704c52ae96a9cdfbc3c4565a39d17f2480d19
…ync respondWith/waitUntil., a=testonly Automatic update from web-platform-tests service worker: Improve WPT tests for async respondWith/waitUntil. (#15852) See discussion at [1] and [2]. This makes the following changes. 1. Adds a test for: self.addEventListener('fetch', e => { Promise.resolve().then(() => { e.respondWith(new Response('hi')); }); }); This should not throw because respondWith() is called while the event dispatch flag is still set. The microtask checkpoint is in "Cleanup After Running Scripts" here: https://html.spec.whatwg.org/multipage/webappapis.html#clean-up-after-running-script This is called from step 16.2 here: https://heycam.github.io/webidl/#call-a-user-objects-operation Which in turn is called from the DOM spec's "Inner Invoke" to call event targets: https://dom.spec.whatwg.org/#concept-event-listener-inner-invoke 2. Changes the expectation for: addEventListener('message', event => { Promise.resolve().then(event.waitUntil(p)); }); From throws to not throws, for the same reasoning as above. 3. Changes the expectation for: addEventListener('message', event => { waitPromise = Promise.resolve(); event.waitUntil(waitPromise); waitPromise.then(() => { Promise.resolve().then(() => {event.waitUntil();}); }); }); From throws to not throws. This is subtle. Because all the promises are just Promise.resolve(), the event dispatch flag is still set by the time the second waitUntil() is called. 4. To test what 3. originally intended, a new test is added which makes waitPromise a promise that does not immediately resolve. 5. Changes the expectation for: addEventListener(‘fetch’, event => { response = Promise.resolve(new Response('RESP')); event.respondWith(response); response.then(() => { Promise.resolve().then(() => {event.waitUntil();}); }) }); Again this is because the promises used resolve immediately, so the event dispatch flag is still set. Similarly, a new test is added to cover the original intent. These WPT changes appear to match the behavior of Safari and Edge while diverging from Chrome and (partially) Firefox. [1] w3c/ServiceWorker#1213 [2] w3c/ServiceWorker#1394 Bug: 942414 Change-Id: I9a4a56d71d3919ed614ff78df2bdc6cc0251dadd Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1524393 Commit-Queue: Matt Falkenhagen <falkenchromium.org> Reviewed-by: Ben Kelly <wanderviewchromium.org> Cr-Commit-Position: refs/heads/master{#641514} -- wpt-commits: cecb3eba4dae3d795876f7b4be71bd49afa03356 wpt-pr: 15852 UltraBlame original commit: a941738d800eb075978e20b17f3a72cb680a8398
…ync respondWith/waitUntil., a=testonly Automatic update from web-platform-tests service worker: Improve WPT tests for async respondWith/waitUntil. (#15852) See discussion at [1] and [2]. This makes the following changes. 1. Adds a test for: self.addEventListener('fetch', e => { Promise.resolve().then(() => { e.respondWith(new Response('hi')); }); }); This should not throw because respondWith() is called while the event dispatch flag is still set. The microtask checkpoint is in "Cleanup After Running Scripts" here: https://html.spec.whatwg.org/multipage/webappapis.html#clean-up-after-running-script This is called from step 16.2 here: https://heycam.github.io/webidl/#call-a-user-objects-operation Which in turn is called from the DOM spec's "Inner Invoke" to call event targets: https://dom.spec.whatwg.org/#concept-event-listener-inner-invoke 2. Changes the expectation for: addEventListener('message', event => { Promise.resolve().then(event.waitUntil(p)); }); From throws to not throws, for the same reasoning as above. 3. Changes the expectation for: addEventListener('message', event => { waitPromise = Promise.resolve(); event.waitUntil(waitPromise); waitPromise.then(() => { Promise.resolve().then(() => {event.waitUntil();}); }); }); From throws to not throws. This is subtle. Because all the promises are just Promise.resolve(), the event dispatch flag is still set by the time the second waitUntil() is called. 4. To test what 3. originally intended, a new test is added which makes waitPromise a promise that does not immediately resolve. 5. Changes the expectation for: addEventListener(‘fetch’, event => { response = Promise.resolve(new Response('RESP')); event.respondWith(response); response.then(() => { Promise.resolve().then(() => {event.waitUntil();}); }) }); Again this is because the promises used resolve immediately, so the event dispatch flag is still set. Similarly, a new test is added to cover the original intent. These WPT changes appear to match the behavior of Safari and Edge while diverging from Chrome and (partially) Firefox. [1] w3c/ServiceWorker#1213 [2] w3c/ServiceWorker#1394 Bug: 942414 Change-Id: I9a4a56d71d3919ed614ff78df2bdc6cc0251dadd Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1524393 Commit-Queue: Matt Falkenhagen <falkenchromium.org> Reviewed-by: Ben Kelly <wanderviewchromium.org> Cr-Commit-Position: refs/heads/master{#641514} -- wpt-commits: cecb3eba4dae3d795876f7b4be71bd49afa03356 wpt-pr: 15852 UltraBlame original commit: b4b704c52ae96a9cdfbc3c4565a39d17f2480d19
https://bugs.webkit.org/show_bug.cgi?id=188246 Reviewed by Darin Adler. LayoutTests/imported/w3c: This test is wrong[1,2]. It starts failing since our worker starts using correct microtask queues. [1]: web-platform-tests/wpt#8936 [2]: w3c/ServiceWorker#1213 (comment) * web-platform-tests/service-workers/service-worker/extendable-event-async-waituntil.https-expected.txt: Source/WebCore: This patch adds the microtask mechanism to workers. To adopt the existing microtask mechanism from the main thread, we extend JSMainThreadExecState for non-main-threads. We rename it to JSExecState, and store stacked ExecState* data in thread local storage in ThreadGlobalData instead of a static variable s_mainThreadState. We add MicrotaskQueue to WorkerGlobalScope since each worker has its own thread and it should have its own microtask queue. * Modules/encryptedmedia/legacy/LegacyCDMSessionClearKey.cpp: * Sources.txt: * WebCore.xcodeproj/project.pbxproj: * bindings/js/JSBindingsAllInOne.cpp: * bindings/js/JSCallbackData.cpp: (WebCore::JSCallbackData::invokeCallback): * bindings/js/JSCustomElementInterface.cpp: (WebCore::constructCustomElementSynchronously): (WebCore::JSCustomElementInterface::upgradeElement): (WebCore::JSCustomElementInterface::invokeCallback): * bindings/js/JSCustomXPathNSResolver.cpp: (WebCore::JSCustomXPathNSResolver::lookupNamespaceURI): * bindings/js/JSDOMGlobalObjectTask.cpp: * bindings/js/JSDOMWindowBase.cpp: (WebCore::JSDOMWindowBase::queueTaskToEventLoop): Queue a microtask to MicrotaskQueue instead of posting a macrotask. (WebCore::JSDOMWindowMicrotaskCallback::create): Deleted. (WebCore::JSDOMWindowMicrotaskCallback::call): Deleted. (WebCore::JSDOMWindowMicrotaskCallback::JSDOMWindowMicrotaskCallback): Deleted. (): Deleted. Extract JSDOMWindowMicrotaskCallback as JSMicrotaskCallback and create a new file for it. * bindings/js/JSErrorHandler.cpp: (WebCore::JSErrorHandler::handleEvent): * bindings/js/JSEventListener.cpp: (WebCore::JSEventListener::handleEvent): * bindings/js/JSExecState.cpp: Renamed from Source/WebCore/bindings/js/JSMainThreadExecState.cpp. (WebCore::JSExecState::didLeaveScriptContext): If we are in a main thread, we consume main thread microtask queue. If we are in worker thread, we consume a microtask queue per worker. (WebCore::functionCallHandlerFromAnyThread): (WebCore::evaluateHandlerFromAnyThread): * bindings/js/JSExecState.h: Renamed from Source/WebCore/bindings/js/JSMainThreadExecState.h. (WebCore::JSExecState::currentState): (WebCore::JSExecState::call): (WebCore::JSExecState::evaluate): (WebCore::JSExecState::profiledCall): (WebCore::JSExecState::profiledEvaluate): (WebCore::JSExecState::runTask): (WebCore::JSExecState::loadModule): (WebCore::JSExecState::linkAndEvaluateModule): (WebCore::JSExecState::JSExecState): (WebCore::JSExecState::~JSExecState): (WebCore::JSExecState::setCurrentState): Store and load ExecState in thread local storage, ThreadGlobalData. This allows us to use it for workers. (WebCore::JSMainThreadNullState::JSMainThreadNullState): (WebCore::JSMainThreadNullState::~JSMainThreadNullState): We keep this name "JSMainThreadNullState" since CustomElementReactionStack should be stick to the main thread. And this class is only used in the main thread. * bindings/js/JSExecStateInstrumentation.h: Renamed from Source/WebCore/bindings/js/JSMainThreadExecStateInstrumentation.h. (WebCore::JSExecState::instrumentFunctionInternal): (WebCore::JSExecState::instrumentFunctionCall): (WebCore::JSExecState::instrumentFunctionConstruct): * bindings/js/JSMicrotaskCallback.h: Copied from Source/WebKitLegacy/mac/DOM/DOMHTMLBaseElement.mm. (WebCore::JSMicrotaskCallback::create): (WebCore::JSMicrotaskCallback::call): (WebCore::JSMicrotaskCallback::JSMicrotaskCallback): * bindings/js/JSWorkerGlobalScopeBase.cpp: (WebCore::JSWorkerGlobalScopeBase::queueTaskToEventLoop): * bindings/js/ScheduledAction.cpp: (WebCore::ScheduledAction::executeFunctionInContext): * bindings/js/ScriptController.cpp: (WebCore::ScriptController::evaluateInWorld): (WebCore::ScriptController::loadModuleScriptInWorld): (WebCore::ScriptController::linkAndEvaluateModuleScriptInWorld): (WebCore::ScriptController::canAccessFromCurrentOrigin): * bindings/js/WorkerScriptController.cpp: (WebCore::WorkerScriptController::evaluate): * bridge/objc/WebScriptObject.mm: (-[WebScriptObject callWebScriptMethod:withArguments:]): (-[WebScriptObject evaluateWebScript:]): * html/canvas/WebGLRenderingContextBase.cpp: (WebCore::WebGLRenderingContextBase::compileShader): (WebCore::WebGLRenderingContextBase::printToConsole): * inspector/InspectorCanvas.cpp: (WebCore::InspectorCanvas::buildObjectForCanvas): (WebCore::InspectorCanvas::buildAction): * inspector/InspectorController.cpp: * inspector/InspectorFrontendHost.cpp: * inspector/TimelineRecordFactory.cpp: (WebCore::TimelineRecordFactory::createGenericRecord): * inspector/WorkerInspectorController.cpp: * inspector/agents/InspectorCanvasAgent.cpp: * inspector/agents/InspectorNetworkAgent.cpp: (WebCore::InspectorNetworkAgent::buildInitiatorObject): * page/DOMWindow.cpp: (WebCore::DOMWindow::postMessage): * page/PageConsoleClient.cpp: (WebCore::PageConsoleClient::addMessage): * page/csp/ContentSecurityPolicy.cpp: (WebCore::ContentSecurityPolicy::reportViolation const): * platform/ThreadGlobalData.h: (WebCore::ThreadGlobalData::ThreadGlobalData::currentState const): (WebCore::ThreadGlobalData::ThreadGlobalData::setCurrentState): * workers/WorkerGlobalScope.cpp: (WebCore::WorkerGlobalScope::WorkerGlobalScope): (WebCore::WorkerGlobalScope::removeMicrotaskQueue): * workers/WorkerGlobalScope.h: (WebCore::WorkerGlobalScope::microtaskQueue const): * workers/WorkerThread.cpp: (WebCore::WorkerThread::stop): * workers/service/ExtendableEvent.cpp: (WebCore::ExtendableEvent::addExtendLifetimePromise): When dispatching an "install" event from service worker, we first create an event, dispatch it, and set a handler which is called when a pending promise count becomes zero. However, the old code checked pending promise count in a queued microtask. It worked previously because microtask is actually a macrotask in the service worker. So this check is done after a handler is set. But this patch introduces real microtask, and this check happens before a handler is set because dispatching an event can exhaust microtask queue. According to the spec, this check should not be done in microtask[1]. We make this checking part as a macrotask. We note that algorithm noted as FIXMEs should be done in this microtask while the checking part should not be done. [1]: https://w3c.github.io/ServiceWorker/#installation-algorithm Source/WebKit: Rename JSMainThreadExecState.h to JSExecState.h. * WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMAttr.cpp: * WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMBlob.cpp: * WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMCDATASection.cpp: * WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMCSSRule.cpp: * WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMCSSRuleList.cpp: * WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMCSSStyleDeclaration.cpp: * WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMCSSStyleSheet.cpp: * WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMCSSValue.cpp: * WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMCharacterData.cpp: * WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMClientRect.cpp: * WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMClientRectList.cpp: * WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMComment.cpp: * WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMDOMImplementation.cpp: * WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMDOMSelection.cpp: * WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMDOMTokenList.cpp: * WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMDOMWindow.cpp: * WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMDeprecated.cpp: * WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMDocumentFragment.cpp: * WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMDocumentGtk.cpp: * WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMDocumentType.cpp: * WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMElementGtk.cpp: * WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMEvent.cpp: * WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMFile.cpp: * WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMFileList.cpp: * WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMHTMLAnchorElement.cpp: * WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMHTMLAppletElement.cpp: * WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMHTMLAreaElement.cpp: * WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMHTMLBRElement.cpp: * WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMHTMLBaseElement.cpp: * WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMHTMLBodyElement.cpp: * WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMHTMLButtonElement.cpp: * WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMHTMLCanvasElement.cpp: * WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMHTMLCollection.cpp: * WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMHTMLDListElement.cpp: * WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMHTMLDirectoryElement.cpp: * WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMHTMLDivElement.cpp: * WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMHTMLDocument.cpp: * WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMHTMLElement.cpp: * WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMHTMLEmbedElement.cpp: * WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMHTMLFieldSetElement.cpp: * WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMHTMLFontElement.cpp: * WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMHTMLFormElement.cpp: * WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMHTMLFrameElement.cpp: * WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMHTMLFrameSetElement.cpp: * WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMHTMLHRElement.cpp: * WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMHTMLHeadElement.cpp: * WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMHTMLHeadingElement.cpp: * WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMHTMLHtmlElement.cpp: * WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMHTMLIFrameElement.cpp: * WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMHTMLImageElement.cpp: * WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMHTMLInputElement.cpp: * WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMHTMLLIElement.cpp: * WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMHTMLLabelElement.cpp: * WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMHTMLLegendElement.cpp: * WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMHTMLLinkElement.cpp: * WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMHTMLMapElement.cpp: * WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMHTMLMarqueeElement.cpp: * WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMHTMLMenuElement.cpp: * WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMHTMLMetaElement.cpp: * WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMHTMLModElement.cpp: * WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMHTMLOListElement.cpp: * WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMHTMLObjectElement.cpp: * WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMHTMLOptGroupElement.cpp: * WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMHTMLOptionElement.cpp: * WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMHTMLOptionsCollection.cpp: * WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMHTMLParagraphElement.cpp: * WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMHTMLParamElement.cpp: * WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMHTMLPreElement.cpp: * WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMHTMLQuoteElement.cpp: * WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMHTMLScriptElement.cpp: * WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMHTMLSelectElement.cpp: * WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMHTMLStyleElement.cpp: * WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMHTMLTableCaptionElement.cpp: * WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMHTMLTableCellElement.cpp: * WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMHTMLTableColElement.cpp: * WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMHTMLTableElement.cpp: * WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMHTMLTableRowElement.cpp: * WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMHTMLTableSectionElement.cpp: * WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMHTMLTextAreaElement.cpp: * WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMHTMLTitleElement.cpp: * WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMHTMLUListElement.cpp: * WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMKeyboardEvent.cpp: * WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMMediaList.cpp: * WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMMouseEvent.cpp: * WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMNamedNodeMap.cpp: * WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMNodeGtk.cpp: * WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMNodeIterator.cpp: * WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMNodeList.cpp: * WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMProcessingInstruction.cpp: * WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMRange.cpp: * WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMStyleSheet.cpp: * WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMStyleSheetList.cpp: * WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMText.cpp: * WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMTreeWalker.cpp: * WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMUIEvent.cpp: * WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMWheelEvent.cpp: * WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMXPathExpression.cpp: * WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMXPathNSResolver.cpp: * WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMXPathResult.cpp: Source/WebKitLegacy/mac: Rename JSMainThreadExecState.h to JSExecState.h. * DOM/DOMAttr.mm: * DOM/DOMBlob.mm: * DOM/DOMCDATASection.mm: * DOM/DOMCSSCharsetRule.mm: * DOM/DOMCSSFontFaceRule.mm: * DOM/DOMCSSImportRule.mm: * DOM/DOMCSSMediaRule.mm: * DOM/DOMCSSPageRule.mm: * DOM/DOMCSSPrimitiveValue.mm: * DOM/DOMCSSRule.mm: * DOM/DOMCSSRuleList.mm: * DOM/DOMCSSStyleDeclaration.mm: * DOM/DOMCSSStyleRule.mm: * DOM/DOMCSSStyleSheet.mm: * DOM/DOMCSSUnknownRule.mm: * DOM/DOMCSSValue.mm: * DOM/DOMCSSValueList.mm: * DOM/DOMCharacterData.mm: * DOM/DOMComment.mm: * DOM/DOMCounter.mm: * DOM/DOMDocument.mm: * DOM/DOMDocumentFragment.mm: * DOM/DOMDocumentType.mm: * DOM/DOMElement.mm: * DOM/DOMEvent.mm: * DOM/DOMFile.mm: * DOM/DOMFileList.mm: * DOM/DOMHTML.mm: * DOM/DOMHTMLAnchorElement.mm: * DOM/DOMHTMLAppletElement.mm: * DOM/DOMHTMLAreaElement.mm: * DOM/DOMHTMLBRElement.mm: * DOM/DOMHTMLBaseElement.mm: * DOM/DOMHTMLBaseFontElement.mm: * DOM/DOMHTMLBodyElement.mm: * DOM/DOMHTMLButtonElement.mm: * DOM/DOMHTMLCanvasElement.mm: * DOM/DOMHTMLCollection.mm: * DOM/DOMHTMLDListElement.mm: * DOM/DOMHTMLDirectoryElement.mm: * DOM/DOMHTMLDivElement.mm: * DOM/DOMHTMLDocument.mm: * DOM/DOMHTMLElement.mm: * DOM/DOMHTMLEmbedElement.mm: * DOM/DOMHTMLFieldSetElement.mm: * DOM/DOMHTMLFontElement.mm: * DOM/DOMHTMLFormElement.mm: * DOM/DOMHTMLFrameElement.mm: * DOM/DOMHTMLFrameSetElement.mm: * DOM/DOMHTMLHRElement.mm: * DOM/DOMHTMLHeadElement.mm: * DOM/DOMHTMLHeadingElement.mm: * DOM/DOMHTMLHtmlElement.mm: * DOM/DOMHTMLIFrameElement.mm: * DOM/DOMHTMLImageElement.mm: * DOM/DOMHTMLInputElement.mm: * DOM/DOMHTMLLIElement.mm: * DOM/DOMHTMLLabelElement.mm: * DOM/DOMHTMLLegendElement.mm: * DOM/DOMHTMLLinkElement.mm: * DOM/DOMHTMLMapElement.mm: * DOM/DOMHTMLMarqueeElement.mm: * DOM/DOMHTMLMediaElement.mm: * DOM/DOMHTMLMenuElement.mm: * DOM/DOMHTMLMetaElement.mm: * DOM/DOMHTMLModElement.mm: * DOM/DOMHTMLOListElement.mm: * DOM/DOMHTMLObjectElement.mm: * DOM/DOMHTMLOptGroupElement.mm: * DOM/DOMHTMLOptionElement.mm: * DOM/DOMHTMLOptionsCollection.mm: * DOM/DOMHTMLParagraphElement.mm: * DOM/DOMHTMLParamElement.mm: * DOM/DOMHTMLPreElement.mm: * DOM/DOMHTMLQuoteElement.mm: * DOM/DOMHTMLScriptElement.mm: * DOM/DOMHTMLSelectElement.mm: * DOM/DOMHTMLStyleElement.mm: * DOM/DOMHTMLTableCaptionElement.mm: * DOM/DOMHTMLTableCellElement.mm: * DOM/DOMHTMLTableColElement.mm: * DOM/DOMHTMLTableElement.mm: * DOM/DOMHTMLTableRowElement.mm: * DOM/DOMHTMLTableSectionElement.mm: * DOM/DOMHTMLTextAreaElement.mm: * DOM/DOMHTMLTitleElement.mm: * DOM/DOMHTMLUListElement.mm: * DOM/DOMHTMLVideoElement.mm: * DOM/DOMImplementation.mm: * DOM/DOMKeyboardEvent.mm: * DOM/DOMMediaError.mm: * DOM/DOMMediaList.mm: * DOM/DOMMouseEvent.mm: * DOM/DOMMutationEvent.mm: * DOM/DOMNamedNodeMap.mm: * DOM/DOMNode.mm: * DOM/DOMNodeIterator.mm: * DOM/DOMNodeList.mm: * DOM/DOMOverflowEvent.mm: * DOM/DOMProcessingInstruction.mm: * DOM/DOMProgressEvent.mm: * DOM/DOMRGBColor.mm: * DOM/DOMRange.mm: * DOM/DOMRect.mm: * DOM/DOMStyleSheet.mm: * DOM/DOMStyleSheetList.mm: * DOM/DOMText.mm: * DOM/DOMTextEvent.mm: * DOM/DOMTimeRanges.mm: * DOM/DOMTokenList.mm: * DOM/DOMTreeWalker.mm: * DOM/DOMUIEvent.mm: * DOM/DOMWheelEvent.mm: * DOM/DOMXPathExpression.mm: * DOM/DOMXPathResult.mm: * DOM/ObjCEventListener.mm: LayoutTests: * http/wpt/workers/microtasks.any-expected.txt: Added. * http/wpt/workers/microtasks.any.html: Added. * http/wpt/workers/microtasks.any.js: Added. (promise_test): * http/wpt/workers/microtasks.any.worker-expected.txt: Added. * http/wpt/workers/microtasks.any.worker.html: Added. Canonical link: https://commits.webkit.org/203435@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@234586 268f45cc-cd09-0410-ab3c-d52691b4dbfc
As you may be aware the firefox Promise implementation has not been using proper microtasks and we're trying to fix that. Part of that effort uncovered an issue with a test for async waitUntil():
https://bugzilla.mozilla.org/show_bug.cgi?id=1409979
Apparently the spec is correct, but the test follows an incorrect interpretation based on our bogus microstask handling. Chrome matched the test expectation by doing this workaround:
https://cs.chromium.org/chromium/src/third_party/WebKit/Source/modules/serviceworkers/WaitUntilObserver.cpp?l=145&rcl=c2665c0a9bfec6379c90d3ea36199ee6a3e9f024
We would like to correct the test to follow the spec and real microtask definition, but wanted to make sure everyone was ok with that since chrome matches behavior.
We think this example from the original issue is incorrect: #1039 (comment)
And this WPT test condition should return OK and not throw an InvalidStateError:
https://github.com/w3c/web-platform-tests/blob/a16738c524a65946b0ff7df6be37ae076ff5e860/service-workers/service-worker/resources/extendable-event-async-waituntil.js#L20
The text was updated successfully, but these errors were encountered: