-
Notifications
You must be signed in to change notification settings - Fork 83
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
Guarding data posts against closing the tab #72
Comments
One of the UIs I suggested for one-off was prompting the user when the application is closed to allow for synchronization when the user goes online next. Basically you can request one-off anytime as it's also a healthy way to not have to ping the network every-so-often until you find you're online again. The UI only comes up when the application is terminated. |
Are you saying |
No, I'm saying that as long as it has clients there's no need to display UI for one-off. Only at the point all clients go away. |
Ahh ok. I don't think that solves the issue as you could still get the race between the fetch from the page & the one in the |
Maybe we should change the semantics of the one-off to fire as quickly as possible when the user is online. That way you can do everything through the one-off. |
Yeah, although communicating success/failure back to the page isn't ideal. Maybe: addToOutbox(importantEmail);
reg.sync.register({tag: 'outbox'}).then(syncReg => {
syncReg.syncNow().then(val => {
console.log(val); // "All done!"
});
}); Over in the service worker: self.addEventListener('sync', event => {
event.waitUntil(
fetch(url, {
method: 'POST',
body: getOutbox()
}).then(r => r.json()).then(data => {
if (data.ok) return "All done!";
throw Error(data.err || "Unknown error");
})
);
}); |
A little more detail: a one-off wouldn't fire as quickly as possible when the user is online, although |
A big problem here is that errors aren't structured-cloneable. Filed https://www.w3.org/Bugs/Public/show_bug.cgi?id=28389 |
Given that a one-shot can only be registered when the page is open, why wouldn't it be fired right away? |
@jkarlin it would, unless you're offline. |
would the following setup take care of the race condition?
Hmm, there might be some instances where the page is gone AND has a message sitting on its plate though... Could the SW, after it's done emptying the outbox, check for the absence of clients and take care of the Page's plate without running into a race condition? |
Yeah, I'm nervous about anything that 'removes' something from an outbox before it's successfully sent. |
So, I encountered this issue when adding background-sync to https://jakearchibald-gcm.appspot.com/chat/
I'm aware of all the horrible race conditions around my use of the outbox, which can be fixed by using IDB properly. However, the real painful bit is the messaging between SW and page. I'm currently broadcasting to all clients after syncing, because I don't have a way to identify the client that initiated the sync. I need to do something on the page to check it's expecting the message it gets (I'm not doing that right now). I'm still keen on something like this: reg.sync.register({tag: 'outbox'}).then(syncReg => {
return syncReg.done;
}).then(_ => {
// sync is complete
}); Where It'd be nice to be able to pass a value back, but that seems a lot more complicated. |
+1, syncReg.done seems useful |
I like that (obviously on one-shot syncs only; I'm not sure what the periodic equivalent would be). It enables some interesting use cases -- it makes a 'background sync status page' easy to implement in Javascript, and makes it much easier for multiple client windows to display UI on pending syncs, even if they weren't the one to register it. |
done is in the spec, closing as fixed. |
Consider this:
If sending an email fails, we request a sync and handle it later. However, if the tab/browser closes before the request completes, or the page navigates away, the request fails but we never get the chance to send that request.
Data isn't lost, but we can't send that email in the background. It becomes more attractive to do this:
As in, we schedule a sync with every important
POST
, and unregister it if it succeeds. I'm worried there may be a race here where the sync event fires file the fetch is still being attempted, resulting in a double fetch.I could schedule a sync event and do all of my outbox emptying there (not from the page at all), but I have no guarantee that it'll happen immediately, and communicating success/failure back to the page is a bit of a
postMessage
mess.Is there anything we can do to improve this? Should we?
Couple of half-baked ideas:
Or:
…which would prevent race conditions with the page.
The text was updated successfully, but these errors were encountered: