From 83f29f7f2f951192e2b52778556c898a9c6ec4b9 Mon Sep 17 00:00:00 2001 From: Jungkee Song Date: Fri, 9 Feb 2018 16:38:56 +0900 Subject: [PATCH 1/2] Improve.ready and Activate Before this change, .ready method was waiting for the change of the state of the regisration's active worker without being synchronized with the steps that set the corresponding ServiceWorkerRegistration object's active ServiceWorker object's state. This changes both .ready and Activate such that .ready tries to resolve the ready promise, if pending, and just returns. And Activate resolves pending ready promises after updating active ServiceWorker object's state. Fixes #1011 --- docs/index.bs | 29 ++++++++++++----------------- docs/v1/index.bs | 29 ++++++++++++----------------- 2 files changed, 24 insertions(+), 34 deletions(-) diff --git a/docs/index.bs b/docs/index.bs index b4af364d..606f6546 100644 --- a/docs/index.bs +++ b/docs/index.bs @@ -576,7 +576,7 @@ spec: webappsec-referrer-policy; urlPrefix: https://w3c.github.io/webappsec-refe A {{ServiceWorkerContainer}} has an associated service worker client, which is a [=/service worker client=] whose [=environment settings object/global object=] is associated with the {{Navigator}} object or the {{WorkerNavigator}} object that the {{ServiceWorkerContainer}} is retrieved from. - A {{ServiceWorkerContainer}} object has an associated ready promise (a promise). It is initially set to a new promise. + A {{ServiceWorkerContainer}} object has an associated ready promise (a [=promise=]). It is initially set to [=a new promise=]. A {{ServiceWorkerContainer}} object has a task source called the client message queue, initially empty. A [=ServiceWorkerContainer/client message queue=] can be enabled or disabled, and is initially disabled. When a {{ServiceWorkerContainer}} object's [=ServiceWorkerContainer/client message queue=] is enabled, the event loop *must* use it as one of its task sources. When the {{ServiceWorkerContainer}} object's relevant global object is a {{Window}} object, all tasks queued on its [=ServiceWorkerContainer/client message queue=] *must* be associated with its relevant settings object's responsible document. @@ -596,22 +596,13 @@ spec: webappsec-referrer-policy; urlPrefix: https://w3c.github.io/webappsec-refe ready attribute *must* run these steps: - 1. If the context object's [=ServiceWorkerContainer/ready promise=] is settled, return the context object's [=ServiceWorkerContainer/ready promise=]. - 1. Let |client| be the context object's [=ServiceWorkerContainer/service worker client=]. - 1. Let |clientURL| be |client|'s creation URL. - 1. Run the following substeps in parallel: - 1. *CheckRegistration*: Let |registration| be the result of running Match Service Worker Registration algorithm with |clientURL|. - 1. If |registration| is null, then: - 1. Wait until scope to registration map has a new entry. - 1. Jump to the step labeled *CheckRegistration*. - 1. If |registration|'s active worker is null, wait until |registration|'s active worker changes. - - Note: Implementers should consider this condition is met when the corresponding registration request gets to the step 6 of Activate algorithm. - - 1. Resolve context object's [=ServiceWorkerContainer/ready promise=] with the {{ServiceWorkerRegistration}} object which represents |registration|. - 1. Return context object's [=ServiceWorkerContainer/ready promise=]. + 1. Let |readyPromise| be the [=context object=]'s [=ServiceWorkerContainer/ready promise=]. + 1. If |readyPromise| is pending, then: + 1. Let |registration| be the result of running [=Match Service Worker Registration=] with the [=context object=]'s [=ServiceWorkerContainer/service worker client=]'s [=creation URL=]. + 1. If |registration| is not null, and |registration|'s [=active worker=] is not null, resolve |readyPromise| with the {{ServiceWorkerRegistration}} object that represents |registration|. + 1. Return |readyPromise|. - Note: When the {{ServiceWorkerContainer/ready}} attribute is accessed, the returned promise will never reject. Instead, it waits until the promise resolves with a [=/service worker registration=] that has an active worker. + Note: The returned [=ServiceWorkerContainer/ready promise=] will never reject. If it does not resolve in this algorithm, it will eventually resolve when a matching [=/service worker registration=] is registered and its [=active worker=] is set. (See the relevant [Activate algorithm step](#activate-resolve-ready-step).)
@@ -2541,7 +2532,11 @@ spec: webappsec-referrer-policy; urlPrefix: https://w3c.github.io/webappsec-refe Note: Once an active worker is activating, neither a runtime script error nor a force termination of the active worker prevents the active worker from getting activated. - 1. For each [=/service worker client=] |client| whose creation URL matches |registration|'s [=service worker registration/scope url=]: + 1. Let |matchedClients| be a [=list=] of [=/service worker clients=] whose creation URL matches |registration|'s [=service worker registration/scope url=]. + 1. [=list/For each=] |client| of |matchedClients|: + 1. Let |readyPromise| be |client|'s [=environment settings object/global object=]'s {{ServiceWorkerContainer}} object's [=ServiceWorkerContainer/ready promise=]. + 1. If |readyPromise| is pending, [=queue a task=] on |readyPromise|'s [=relevant settings object=]'s [=responsible event loop=], using the [=DOM manipulation task source=], to resolve |readyPromise| with the {{ServiceWorkerRegistration}} object that represents |registration| in |readyPromise|'s [=relevant Realm=]. + 1. [=list/For each=] |client| of |matchedClients|: 1. If |client| is a window client, unassociate |client|'s responsible document from its application cache, if it has one. 1. Else if |client| is a shared worker client, unassociate |client|'s [=environment settings object/global object=] from its application cache, if it has one. diff --git a/docs/v1/index.bs b/docs/v1/index.bs index cd4e5407..f06a5564 100644 --- a/docs/v1/index.bs +++ b/docs/v1/index.bs @@ -558,7 +558,7 @@ spec: webappsec-referrer-policy; urlPrefix: https://w3c.github.io/webappsec-refe A {{ServiceWorkerContainer}} has an associated service worker client, which is a [=/service worker client=] whose [=environment settings object/global object=] is associated with the {{Navigator}} object or the {{WorkerNavigator}} object that the {{ServiceWorkerContainer}} is retrieved from. - A {{ServiceWorkerContainer}} object has an associated ready promise (a promise). It is initially set to a new promise. + A {{ServiceWorkerContainer}} object has an associated ready promise (a [=promise=]). It is initially set to [=a new promise=]. A {{ServiceWorkerContainer}} object has a task source called the client message queue, initially empty. A [=ServiceWorkerContainer/client message queue=] can be enabled or disabled, and is initially disabled. When a {{ServiceWorkerContainer}} object's [=ServiceWorkerContainer/client message queue=] is enabled, the event loop *must* use it as one of its task sources. When the {{ServiceWorkerContainer}} object's relevant global object is a {{Window}} object, all tasks queued on its [=ServiceWorkerContainer/client message queue=] *must* be associated with its relevant settings object's responsible document. @@ -578,22 +578,13 @@ spec: webappsec-referrer-policy; urlPrefix: https://w3c.github.io/webappsec-refe ready attribute *must* run these steps: - 1. If the context object's [=ServiceWorkerContainer/ready promise=] is settled, return the context object's [=ServiceWorkerContainer/ready promise=]. - 1. Let |client| be the context object's [=ServiceWorkerContainer/service worker client=]. - 1. Let |clientURL| be |client|'s creation URL. - 1. Run the following substeps in parallel: - 1. *CheckRegistration*: Let |registration| be the result of running Match Service Worker Registration algorithm with |clientURL|. - 1. If |registration| is null, then: - 1. Wait until scope to registration map has a new entry. - 1. Jump to the step labeled *CheckRegistration*. - 1. If |registration|'s active worker is null, wait until |registration|'s active worker changes. - - Note: Implementers should consider this condition is met when the corresponding registration request gets to the step 6 of Activate algorithm. - - 1. Resolve context object's [=ServiceWorkerContainer/ready promise=] with the {{ServiceWorkerRegistration}} object which represents |registration|. - 1. Return context object's [=ServiceWorkerContainer/ready promise=]. + 1. Let |readyPromise| be the [=context object=]'s [=ServiceWorkerContainer/ready promise=]. + 1. If |readyPromise| is pending, then: + 1. Let |registration| be the result of running [=Match Service Worker Registration=] with the [=context object=]'s [=ServiceWorkerContainer/service worker client=]'s [=creation URL=]. + 1. If |registration| is not null, and |registration|'s [=active worker=] is not null, resolve |readyPromise| with the {{ServiceWorkerRegistration}} object that represents |registration|. + 1. Return |readyPromise|. - Note: When the {{ServiceWorkerContainer/ready}} attribute is accessed, the returned promise will never reject. Instead, it waits until the promise resolves with a [=/service worker registration=] that has an active worker. + Note: The returned [=ServiceWorkerContainer/ready promise=] will never reject. If it does not resolve in this algorithm, it will eventually resolve when a matching [=/service worker registration=] is registered and its [=active worker=] is set. (See the relevant [Activate algorithm step](#activate-resolve-ready-step).)
@@ -2414,7 +2405,11 @@ spec: webappsec-referrer-policy; urlPrefix: https://w3c.github.io/webappsec-refe Note: Once an active worker is activating, neither a runtime script error nor a force termination of the active worker prevents the active worker from getting activated. - 1. For each [=/service worker client=] |client| whose creation URL matches |registration|'s [=service worker registration/scope url=]: + 1. Let |matchedClients| be a [=list=] of [=/service worker clients=] whose creation URL matches |registration|'s [=service worker registration/scope url=]. + 1. [=list/For each=] |client| of |matchedClients|: + 1. Let |readyPromise| be |client|'s [=environment settings object/global object=]'s {{ServiceWorkerContainer}} object's [=ServiceWorkerContainer/ready promise=]. + 1. If |readyPromise| is pending, [=queue a task=] on |readyPromise|'s [=relevant settings object=]'s [=responsible event loop=], using the [=DOM manipulation task source=], to resolve |readyPromise| with the {{ServiceWorkerRegistration}} object that represents |registration| in |readyPromise|'s [=relevant Realm=]. + 1. [=list/For each=] |client| of |matchedClients|: 1. If |client| is a window client, unassociate |client|'s responsible document from its application cache, if it has one. 1. Else if |client| is a shared worker client, unassociate |client|'s [=environment settings object/global object=] from its application cache, if it has one. From 77eb154ab9294705780e37e307eae1671f8169b5 Mon Sep 17 00:00:00 2001 From: Jungkee Song Date: Mon, 12 Feb 2018 15:11:21 +0900 Subject: [PATCH 2/2] Run registration mathcing in parallel; manipulate ready promise on the main thread --- docs/index.bs | 8 ++++---- docs/v1/index.bs | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/docs/index.bs b/docs/index.bs index 606f6546..937a24e4 100644 --- a/docs/index.bs +++ b/docs/index.bs @@ -597,9 +597,9 @@ spec: webappsec-referrer-policy; urlPrefix: https://w3c.github.io/webappsec-refe ready attribute *must* run these steps: 1. Let |readyPromise| be the [=context object=]'s [=ServiceWorkerContainer/ready promise=]. - 1. If |readyPromise| is pending, then: + 1. If |readyPromise| is pending, run the following substeps [=in parallel=]: 1. Let |registration| be the result of running [=Match Service Worker Registration=] with the [=context object=]'s [=ServiceWorkerContainer/service worker client=]'s [=creation URL=]. - 1. If |registration| is not null, and |registration|'s [=active worker=] is not null, resolve |readyPromise| with the {{ServiceWorkerRegistration}} object that represents |registration|. + 1. If |registration| is not null, and |registration|'s [=active worker=] is not null, [=queue a task=] on |readyPromise|'s [=relevant settings object=]'s [=responsible event loop=], using the [=DOM manipulation task source=], to resolve |readyPromise| with the {{ServiceWorkerRegistration}} object that represents |registration| in |readyPromise|'s [=relevant Realm=]. 1. Return |readyPromise|. Note: The returned [=ServiceWorkerContainer/ready promise=] will never reject. If it does not resolve in this algorithm, it will eventually resolve when a matching [=/service worker registration=] is registered and its [=active worker=] is set. (See the relevant [Activate algorithm step](#activate-resolve-ready-step).) @@ -2533,9 +2533,9 @@ spec: webappsec-referrer-policy; urlPrefix: https://w3c.github.io/webappsec-refe Note: Once an active worker is activating, neither a runtime script error nor a force termination of the active worker prevents the active worker from getting activated. 1. Let |matchedClients| be a [=list=] of [=/service worker clients=] whose creation URL matches |registration|'s [=service worker registration/scope url=]. - 1. [=list/For each=] |client| of |matchedClients|: + 1. [=list/For each=] |client| of |matchedClients|, [=queue a task=] on |client|'s [=responsible event loop=], using the [=DOM manipulation task source=], to run the following substeps: 1. Let |readyPromise| be |client|'s [=environment settings object/global object=]'s {{ServiceWorkerContainer}} object's [=ServiceWorkerContainer/ready promise=]. - 1. If |readyPromise| is pending, [=queue a task=] on |readyPromise|'s [=relevant settings object=]'s [=responsible event loop=], using the [=DOM manipulation task source=], to resolve |readyPromise| with the {{ServiceWorkerRegistration}} object that represents |registration| in |readyPromise|'s [=relevant Realm=]. + 1. If |readyPromise| is pending, resolve |readyPromise| with the {{ServiceWorkerRegistration}} object that represents |registration| in |readyPromise|'s [=relevant Realm=]. 1. [=list/For each=] |client| of |matchedClients|: 1. If |client| is a window client, unassociate |client|'s responsible document from its application cache, if it has one. 1. Else if |client| is a shared worker client, unassociate |client|'s [=environment settings object/global object=] from its application cache, if it has one. diff --git a/docs/v1/index.bs b/docs/v1/index.bs index f06a5564..230048fa 100644 --- a/docs/v1/index.bs +++ b/docs/v1/index.bs @@ -579,9 +579,9 @@ spec: webappsec-referrer-policy; urlPrefix: https://w3c.github.io/webappsec-refe ready attribute *must* run these steps: 1. Let |readyPromise| be the [=context object=]'s [=ServiceWorkerContainer/ready promise=]. - 1. If |readyPromise| is pending, then: + 1. If |readyPromise| is pending, run the following substeps [=in parallel=]: 1. Let |registration| be the result of running [=Match Service Worker Registration=] with the [=context object=]'s [=ServiceWorkerContainer/service worker client=]'s [=creation URL=]. - 1. If |registration| is not null, and |registration|'s [=active worker=] is not null, resolve |readyPromise| with the {{ServiceWorkerRegistration}} object that represents |registration|. + 1. If |registration| is not null, and |registration|'s [=active worker=] is not null, [=queue a task=] on |readyPromise|'s [=relevant settings object=]'s [=responsible event loop=], using the [=DOM manipulation task source=], to resolve |readyPromise| with the {{ServiceWorkerRegistration}} object that represents |registration| in |readyPromise|'s [=relevant Realm=]. 1. Return |readyPromise|. Note: The returned [=ServiceWorkerContainer/ready promise=] will never reject. If it does not resolve in this algorithm, it will eventually resolve when a matching [=/service worker registration=] is registered and its [=active worker=] is set. (See the relevant [Activate algorithm step](#activate-resolve-ready-step).) @@ -2406,9 +2406,9 @@ spec: webappsec-referrer-policy; urlPrefix: https://w3c.github.io/webappsec-refe Note: Once an active worker is activating, neither a runtime script error nor a force termination of the active worker prevents the active worker from getting activated. 1. Let |matchedClients| be a [=list=] of [=/service worker clients=] whose creation URL matches |registration|'s [=service worker registration/scope url=]. - 1. [=list/For each=] |client| of |matchedClients|: + 1. [=list/For each=] |client| of |matchedClients|, [=queue a task=] on |client|'s [=responsible event loop=], using the [=DOM manipulation task source=], to run the following substeps: 1. Let |readyPromise| be |client|'s [=environment settings object/global object=]'s {{ServiceWorkerContainer}} object's [=ServiceWorkerContainer/ready promise=]. - 1. If |readyPromise| is pending, [=queue a task=] on |readyPromise|'s [=relevant settings object=]'s [=responsible event loop=], using the [=DOM manipulation task source=], to resolve |readyPromise| with the {{ServiceWorkerRegistration}} object that represents |registration| in |readyPromise|'s [=relevant Realm=]. + 1. If |readyPromise| is pending, resolve |readyPromise| with the {{ServiceWorkerRegistration}} object that represents |registration| in |readyPromise|'s [=relevant Realm=]. 1. [=list/For each=] |client| of |matchedClients|: 1. If |client| is a window client, unassociate |client|'s responsible document from its application cache, if it has one. 1. Else if |client| is a shared worker client, unassociate |client|'s [=environment settings object/global object=] from its application cache, if it has one.