9

I have a service worker. Here's the install event:

self.addEventListener('install', function (event) {
    console.log('Installing Service Worker ...', event);

    return self.skipWaiting()
    .then(() => caches.open(CACHE_STATIC_NAME))
    .then(function (cache) {
        return cache.addAll([
            './file1.html',
            './file2.html'
        ])
    })
});

For some reason, when I edit the service worker code and update the query parameter in the service worker file URL, it installs but does not activate (according to Chrome DevTools) — even though I've called self.skipWaiting().

Oddly if I go into the console, go to the scope of the service worker and type self.skipWaiting() myself, it activates immediately.

I've been trying to work out what's going on for many hours now, and I'm completely stumped. Is there something I'm missing here?

Ethan
  • 3,410
  • 1
  • 28
  • 49
  • 4
    Same problem here. SW refuses to skipWaiting().. – REJH Mar 01 '19 at 13:44
  • I still haven't solved it, unfortunately :( – Ethan Mar 02 '19 at 03:38
  • 2
    I see your issue and raise you a https://i.imgur.com/JtzlcIM.gifv – Cillié Malan Jun 25 '19 at 08:35
  • 1
    After upgrading to create-react-app v3 and workbox I started to have the same issue, calling `self.skipWaiting()` does not work but clicking `skipWaiting` button on dev tools does the trick, same if I hit page reload button several times in a row – fen1ksss Dec 05 '19 at 15:59

2 Answers2

9

The old SW might not stop while it's still running tasks - for example if it had a long running fetch request (e.g server sent events / event source, or fetch streams; although I don't think websockets can cause this as SW will ignore them I think).

I find the behaviour to be different between browers however. Chrome seems to wait while the existing task is running (so skipWaiting will fail...), but Safari seems to kill the task and activate the new SW.

A good way to test if this is causing your issue would be to kill your server just after you request the skipWaiting (to kill the network connections). (Just clicking "Offline" in Dev Tools doesn't seem to kill all running connections, for example EventSources stay running.)

You can have the SW ignore certain routes (below), or you could try and force the requests to terminate (maybe using AbortController).

self.addEventListener('fetch', function(event) {
  const { method, url } = event.request;
  if(event.request.method !== "GET") return false;
  if(url === "https://example.com/poll") return false;

  event.respondWith(
    caches.match(match).then(function(response) {
      return response || fetch(event.request);
    })
  );
});

The process for skipWaiting is in this spec:

https://w3c.github.io/ServiceWorker/#try-activate-algorithm

But I don't find it very clear about whether the browser should wait for tasks or terminate them (or transfer them to the new SW?), before activating the new SW; and as mentioned, it seems to work differently between browsers at the moment...

ej.daly
  • 276
  • 4
  • 6
  • I can confirm that returning `false` from the fetch event listener for polling related requests and non-GET requests causes my `self.skipWaiting()` to work, but the downside is that those polling requests do need to be made, and when I `return fetch(event.request)` instead of `return false`, the `self.skipWaiting()` call no longer has any effect. Is there a way to allow the polling requests through while still getting `self.skipWaiting()` to work? – Raphael Rafatpanah May 10 '22 at 00:37
0

I had experienced the same issue.

I validated my issue by the trick given by @ej.daly that I should stop the server & the WAITING service-worker will become active in few minutes.

After that, I applied a hack in my code: Reload the window if the WAITING service worker isn't activated in next 3 seconds.

BTW, I am developing a library to make service-worker installation easy for the various (commonly used) scenarios in our company. Have a look at https://github.com/DreamworldSolutions/workbox-installer

chirag
  • 172
  • 7