-
Notifications
You must be signed in to change notification settings - Fork 823
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
v4 Background Sync API updates #1710
Conversation
What about some means of mapping over the queue? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Generally 👍 with the overall approach! I did have a few comments about the public interface, though.
98415b7
to
a226808
Compare
PR-Bot Size PluginChanged File Sizes
New Files
All File SizesView Table
Workbox Aggregate Size Plugin9.71KB gzip'ed (65% of limit) |
@bennypowers, Jeff and I discussed something like this: for await (const entry of queue.entries()) {
try {
await fetch(entry.request);
} catch (error) {
await this.unshiftRequest(entry);
break;
}
} But unfortunately that would require async iterators, which aren't supported in Edge. We could add a queue.forEachRequest(async (entryPromise) => {
// But calling `return` here won't exit the loop...
}) Is that what you were envisioning by your suggestion? I think given the limitations of both options a |
It's clunky but if it's all we have...
|
R: @jeffposnick
Addresses #1424, #1502, #1503, #1637, and #1695.
Based on lots of feedback in the above issues/PRs, its clear that the callbacks provided in
workbox.backgroundSync.Queue
are not sufficient to handle many real-world background sync needs.This PR attempts to solve this issue by exposing more low-level features of the queue, which should give developers all the flexibility they need; the downside is it may make very simple replay modifications a bit more complicated. Hopefully (due to the complex nature of background sync in general), this downside will affect very few people.
Current API:
In Workbox v3, the
workbox.backgroundSync.Queue
class had the following public methods:addRequest()
replayRequests()
And the following replay callbacks that allowed you modify requests as the queue was replaying:
requestWillEnqueue
requestWillReplay
queueDidReplay
But if you wanted to do something other than simply replay every single request, it was very difficult if not impossible. For example, you couldn't easily:
Proposed changes:
To support the above use cases, the changes in this PR remove the
callbacks
object and replace it with a singleonSync
callback. TheonSync
callback will be invoked whenever the queue receives async
event (or at SW startup in non-sync browsers), and if you don't specify anonSync
callback, the default behavior is to runreplayRequests()
like in v3 (but without invoking the v3 callbacks).The
onSync
callback is invoked with thequeue
instance as its only argument, allowing you to handle the queue however you want in response to async
event.In addition, the
workbox.backgroundSync.Queue
class has removed theaddRequest()
method, and replaced it with four array-like methods to make it easier to manage queued requests manually.pushRequest()
popRequests()
shiftRequest()
unshiftRequests()
The
push
andunshift
methods take an object in the form{request, [metadata], [timestamp]}
(onlyrequest
is required), and theshift
andpop
methods return an object in exactly the same form.The optional
metadata
property allows you to store data associated with the request in the queue that may be relevant when re-fetching the request later.The optional
timestamp
property defaults to the current time, and it affects when requests expire. Normally you don't need to pass this, but it can be useful if you want to explicitly reset the expiry time for a particular request in order to keep it in the queue longer.Example
onSync
callbackTo replay all requests in the queue after a sync event, you could do the following:
Note: when using an
async
function for theonSync
callback (recommended) thesync
event automatically waits for the function to complete, so you don't have to manually callevent.waitUntil()
.Using the
Plugin
classSince the plugin class mostly just shadows the
Queue
class, you can pass theonSync
callback to plugin instances in exactly the same way.Note that when using the plugin, the
onSync
callback is still invoked with aQueue
instance, so you don't have to create a reference to the queue yourself.Open questions
By removing the
callback
object in favor of a singleonSync
callback, one thing that is harder to accomplish is notifying of a successful queue replay in situations where you don't want to modify the replay logic.With the changes in this PR, it's still possible, it's just perhaps not as intuative as before. Here's what you'd have to do:
If you want to notify of success and failure, you can use a try/catch block:
Since the above examples are both pretty simple, I'm leaning toward not having onsuccess or onfailure callbacks like before, but if enough people want them, I could be persuaded otherwise.