Search code examples
service-workerworkbox

Should workbox-backround-sync auto detect device is back online


I have been experimenting with workbox service worker toolkit.

The copy here suggests that the workbox-backround-sync QueuePlugin will catch failed requests and later replay them back. So with a bit of a digging I discovered how to get this working on POST method calls.

But the replaying of requests seems a bit hit and miss. Using Chrome dev tools to take the app offline, does indeed place the requests in a queue within IndexedDB. Nothing seemed to be happening and I wanted to debug. I noted that in the demo on github it uses a BroadcastChannel to trigger the replay. So I implemented that. Then from the console in the active tab, I unchecked offline in dev tools and I sent a postMessage. Now the requests fired off happily and the responses were stored for each item in the queue.

I then left the machine running, go into standby etc for a couple of hours. I then noted in the logs that it had happily been sending duplicate requests even though every item had a response.

At this point I try and replicate but can't. I send a BroadcastChannel message and it only fires of requests without responses. So I now go back to the start, and make more offline requests, confirm they are in the DB, restore online and wait. Nothing.

I see that in the constructor of Queue it creates a new RequestManager and in the constructor of that it sets up the sync event listener. So I am guessing that it should be doing something at some point.

I just want to be sure I understand the expected behaviour if someone can help.

Here is the code I have in place.

let bgQueue = new workbox.backgroundSync.QueuePlugin({
  callbacks: {
    onResponse: async(hash, res) => {
      console.log(hash, res);
    }
  }
});

const requestWrapper = new workbox.runtimeCaching.RequestWrapper({
  plugins: [bgQueue]
});

const route = new workbox.routing.RegExpRoute({
  regExp: new RegExp('^http://localhost:4200/api/create/note'),
  handler: new workbox.runtimeCaching.NetworkOnly({requestWrapper}),
  method: 'POST' // Not obvious you need to do this in the docs without digging.
});

const router = new workbox.routing.Router();
router.registerRoute({route});

// Code to manaully trigger a replay.
const replayBroadcastChannel = new BroadcastChannel('replay_channel');
replayBroadcastChannel.onmessage = function() {
  bgQueue.replayRequests();
};

Testing in Chrome 58 on macOS Sierra.


Solution

  • I guess flipping offline -> online -> offline via dev tools wont trigger sync for you(neither will "sync" option in this case), so I am afraid you will have to toggle network on->off from your system.

    Upon doing so, you should be able to see the requests getting replayed just as you thought.

    Also if you are still able to reproduce the duplicate requests(requests which have been responded with 2XX response) please feel free to open a bug.