What should I do with the redundant state of a ServiceWorker?

18,841

Solution 1

Based on the definition here https://www.w3.org/TR/service-workers/#service-worker-state-attribute I am guessing just print a log in case it comes up in debugging otherwise do nothing.

Solution 2

It's kinda difficult to work out what your intent is here so I'll try and answer the question generally.

A service worker will become redundant if it fails to install or if it's superseded by a newer service worker.

What you do when this happens is up to you. What do you want to do in these cases?

Solution 3

You should remove any UI prompts you created that ask the user to do something in order to activate the latest service worker. And be patient a little longer.

You have 3 service workers, as you can see on the registration:

  1. active: the one that is running
  2. waiting: the one that was downloaded, and is ready to become active
  3. installing: the one that we just found, being downloaded, after which it becomes waiting

When a service worker reaches #2, you may display a prompt to the user about the new version of the app being just a click away. Let's say they don't act on it.

Then you publish a new version. Your app detects the new version, and starts to download it. At this point, you have 3 service workers. The one at #2 changes to redundant. The one at #3 is not ready yet. You should remove that prompt.

Once #3 is downloaded, it takes the place of #2, and you can show that prompt again.

Solution 4

Write catch function to see the error. It could be SSL issue.

/* In main.js */
if ('serviceWorker' in navigator) {
    navigator.serviceWorker.register('./sw.js')
    .then(function(registration) {
        console.log("Service Worker Registered", registration);
    })
    .catch(function(err) {
        console.log("Service Worker Failed to Register", err);
    })
}
Share:
18,841
Marvin Danig
Author by

Marvin Danig

Half-blood Geek.

Updated on August 14, 2022

Comments

  • Marvin Danig
    Marvin Danig almost 2 years

    I gotta a companion script for a serviceworker and I'm trialling right now.

    The script works like so:

    ((n, d) => {
    
      if (!(n.serviceWorker && (typeof Cache !== 'undefined' && Cache.prototype.addAll))) return; 
    
      n.serviceWorker.register('/serviceworker.js', { scope: './book/' })
        .then(function(reg) {
    
            if (!n.serviceWorker.controller) return;
    
            reg.onupdatefound = () => {
    
              let installingWorker = reg.installing;
    
              installingWorker.onstatechange = () => {
                switch (installingWorker.state) {
                  case 'installed':
                    if (navigator.serviceWorker.controller) {
                      updateReady(reg.waiting);
    
                    } else {
                      // This is the initial serviceworker…
                      console.log('May be skipwaiting here?');
                    }
                    break;
    
                  case 'waiting':
                    updateReady(reg.waiting);
                    break;
    
                  case 'redundant':
                    // Something went wrong?
                    console.log('[Companion] new SW could not install…')
                    break;
                }
              };
            };
        }).catch((err) => {
          //console.log('[Companion] Something went wrong…', err);
        });
    
        function updateReady(worker) {
            d.getElementById('swNotifier').classList.remove('hidden');
    
            λ('refreshServiceWorkerButton').on('click', function(event) {
              event.preventDefault();
              worker.postMessage({ 'refreshServiceWorker': true } );
            });
    
            λ('cancelRefresh').on('click', function(event) {
              event.preventDefault();
              d.getElementById('swNotifier').classList.add('hidden');
            });
    
        }
    
        function λ(selector) {
    
          let self = {};
    
          self.selector = selector;
    
          self.element = d.getElementById(self.selector);
    
          self.on = function(type, callback) {
            self.element['on' + type] = callback;
          };
    
          return self;
        }
    
        let refreshing;
    
        n.serviceWorker.addEventListener('controllerchange', function() {
          if (refreshing) return;
          window.location.reload();
          refreshing = true;
        });    
    
    
    })(navigator, document);
    

    I'm a bit overwhelmed right now by the enormity of the service workers api and unable to "see" what one would do with reg.installing returning a redundant state?

    Apologies if this seems like a dumb question but I'm new to serviceworkers.

  • Marvin Danig
    Marvin Danig over 7 years
    What are the choices? As @jason livesay suggested I don't see there's much to do with a redundant worker other than console.logging it.
  • JaffaTheCake
    JaffaTheCake over 7 years
    You might want to notify the user, or retry updating/registering sometime later.