[w3c/ServiceWorker] "Unregister" operation may be interrupted by `ServiceWorker#postMessage` (#1146)

Consider the following code:

```js
// Precondition: `registration`is a valid ServiceWorkerRegistration object
// whose "active" worker has no pending events
registration.unregister()
  .then(function() {
      registration.active.postMessage('');
    });
```

"unregistration" involves the following sequence:

1. **Queue a task** to resolve the promise (via Resolve Job Promise)
2. If the active worker has no pending events (via Try Clear Registration)
   1. Terminate the active worker (via Clear Registration)
      1. Set the worker's "closing" flag to `true`
   2. **Queue a task** to set the `state` attribute of the active worker to
      "redundant" (via Update Worker State)
   3. **Queue a task** to set the registration's `active` property to `null`
      (via Update Registration State)


This means the `state` attribute is not set until *after* the promise has been
resolved and any subsequent microtasks processed. Here, the `postMessage`
invocation is part of such a microtask, so when it references the worker's
`state`, it receives the value "active". Execution of the `postMessage`
algorithm proceeds to step 4, where Run Service Worker is invoked. This creates
a new ServiceWorkerGlobalScope object, effectively undoing the prior invocation
of Terminate Worker.

Chromium's behavior more or less adheres to this interpretation, although the
worker's script is only evaluated one time (I would expect a second evaluation
for that invocation of Run Service Worker). Firefox throws an error named
`NS_ERROR_FAILURE` from the `postMessage` invocation. In either case, this
seems like a spec bug--the "unregister" operation is being interrupted, but the
worker state is still ultimately set to "redundant."

Distinguishing between "user-requested un-registration" and "user-agent
requested termination" seems necessary in order to decide whether to throw or
re-start the worker. Making this determination may not be possible from an
arbitrary `postMessage` invocation without the introduction of additional
state or a modification to the schedule of operations in Clear Registration.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/w3c/ServiceWorker/issues/1146

Received on Thursday, 18 May 2017 19:14:11 UTC