question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Observe queue operations when using background sync

See original GitHub issue

We are currently trying to reflect the actual queue contents into the main menu - using a counter representing pending updates (see picture):

To do so, we are using the brand new getAll() method on the Queue object. Rather than showing this kind of information on a regular basis (typically upon application startup + every x seconds/minutes), we would like to be able to do it in real-time.

For this, we need to listen/observe the queue operations, especially:

  • each time a new request is enqueued
  • each time an existing request is dequeued (replayed)

Would it be possible to register some queue listeners (or trigger some events) in order to get notified after each successful pushRequest() and popRequest() so that I can respectively increase or decrease my applicative counter ?

IMHO, it’s not a huge job…

Issue Analytics

  • State:open
  • Created 4 years ago
  • Reactions:8
  • Comments:7 (2 by maintainers)

github_iconTop GitHub Comments

9reactions
blignycommented, Apr 25, 2019

Yes, I have read that post too. I fully understand (and respect) the motivations of this refactoring: the api is now much easier, at least for basic usage. The main objection I have is that we basically have (only) two options:

  • either use the standard/default replay logic (eg queue.replayRequests() )
  • or implement from-scratch a custom replay logic

It’s a bit a kind of ‘all-or-nothing’ choice.

Beside the standard or custom implementations, it would be really great to have a third option: extend/enrich the standard replay skeleton, and focus on extensions.

Of course, this kind of extension is trivial:

const queue = new workbox.backgroundSync.Queue('my-queue-name', {
  onSync: async (queue) => {
    // Run standard replay
    await queue.replayRequests();
    // Do custom *POST* processing (eg update my applicative counter)
    console.log('Extra feature');
  }
});

but it’s limited to the POST processing of the WHOLE backlog.

How (without repeating the skeleton) to add custom processing INSIDE the loop for each INDIVIDUAL queue item ? The only solution is to copy&paste original replayRequests, and then modifying this code:

const queue = new workbox.backgroundSync.Queue('my-queue-name', {
  onSync: async (queue) => {
    let entry;
    while (entry = await this.shiftRequest()) {
      try {
        await fetch(entry.request);
        // Do custom *INNER* processing (eg decrease my applicative counter by one)
       console.log('Extra feature for request', entry.request.url);
      } catch (error) {       
        await this.unshiftRequest(entry);
        throw error;
      }
    }
    console.log('Replay complete!');
  }
});

Yes it works, but it may sometimes be a pity to repeat 10 lines of source code in order to add one single line 😦

In particular, each time I want the use the standard replay logic + one very little additional feature, I always have to repeat the same skeleton (the loop with shiftRequest, the fetch, the unshift in case of error, etc…). And if you fix a bug in the replayRequests() method - like you recently did by replacing fetch(entry.request) with fetch(entry.request.clone()) - my implementation will not benefit from this fix.

Does this meet your needs?

I’m afraid not. My use case is not fully covered. I could indeed implement a custom replay logic in order to decrease my applicative counter, upon the ‘sync’ event, true. But how do I handle the incrementation of my counter ? How can I be notified when the bg-sync plugin is putting a new request into the queue ?

My 2 cents

Bernard.

3reactions
realtebocommented, Sep 22, 2020

I suggest this updated version: note the queue destrctured from param

onSync: async ({queue}) => {
      let entry;
      while ((entry = await queue.shiftRequest())) {
        try {
          await fetch(entry.request);
          console.error("Replay successful for request", entry.request);
        } catch (error) {
          console.error("Replay failed for request", entry.request, error);

          // Put the entry back in the queue and re-throw the error:
          await queue.unshiftRequest(entry);
          throw error;
        }
      }
      console.log("Replay complete!");
    }
Read more comments on GitHub >

github_iconTop Results From Across the Web

workbox-background-sync - Chrome Developers
A class to manage storing requests from a Queue in IndexedDB, indexed by their queue name for easier access. Most developers will not...
Read more >
Service Workers: when does the browser sync back again?
So, as of today, the background-sync in Chrome tries to push the queued ... The queue will sync with the server once you...
Read more >
Background Work Overview | Android Developers
This guide explains what qualifies as background work, defines background task categories, provides you with criteria to categorize your tasks, ...
Read more >
OperationQueue | Apple Developer Documentation
Operation queues use the Dispatch framework to initiate the execution of their operations. As a result, queues always invoke operations on a separate...
Read more >
Understanding Schedulers in Swift Combine Framework
Scheduler is the synchronization mechanism of the Combine ... You'll commonly use serial and global queues for the background work, ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found