Skip to content

Instantly share code, notes, and snippets.

@jugglinmike
Last active May 17, 2017 19:07
Show Gist options
  • Save jugglinmike/773287f814261dd38787de219f638f6f to your computer and use it in GitHub Desktop.
Save jugglinmike/773287f814261dd38787de219f638f6f to your computer and use it in GitHub Desktop.
Service Worker investigation

Consider the following code:

// Precondition: `registration`is a valid ServiceWorkerRegistration object with
// a valid "active" worker with 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. 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."

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment