Skip to content
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

"unload" event and Service Workers #731

Closed
matthewbauer opened this issue Aug 14, 2015 · 6 comments
Closed

"unload" event and Service Workers #731

matthewbauer opened this issue Aug 14, 2015 · 6 comments

Comments

@matthewbauer
Copy link

A common use case of IndexedDB is to save state during the "beforeunload" event. Because IndexedDB is asynchronous, this operation is unsupported behavior according to the specs although it's hit or miss on browser implementations.

I think this kind of "save on exit" operation could be possible with Service Workers but I want to confirm that there is consensus that this should be supported behavior.

Take for example a web game:

// page context

navigator.serviceWorker.register('serviceWorker.js');

var saveData = new Uint8Array(); // memory store with binary data

window.onunload = function() {
  // postMessage should be synchronous in this context?
  navigator.serviceWorker.controller.postMessage({
    type: 'save',
    save: saveData,
    slot: 1
  });
};
// serviceWorker.js

self.onmessage = function(event) {
  if (event.data.type === 'save') {
    // async saving of event.data.save
  }
};
@wanderview
Copy link
Member

It seems to me this should work. You would probably want an event.waitUntil() in your service worker to ensure it lives until your done saving the data.

@annevk
Copy link
Member

annevk commented Aug 15, 2015

It's unclear to me we want the service worker to outlive the lifetime of its closed browsing contexts by default. The user closed the browsing contexts and probably doesn't expect them to able to monitor the user for the next minute or so. (I believe Chrome lets you keep the service worker alive for five minutes, but that seems like a gross privacy violation.)

@matthewbauer
Copy link
Author

What kind of monitoring is actually possible with Service Workers? The lifetime of a service worker can only be extended through a promise from an ExtendableEvent and right now only "install", "activate", and "message" extend it. So, I think that any of these events could extend past a context close. But, from there what user information is really available? Once the client is closed the Service Worker should be confined to previously gathered information. I suppose there could be some clever abuses of the Web Worker context but even that should be confined to the same-origin policy.

The spec right now leaves the max lifetime up to browser vendors. So, the spec should plan for a browser vendor having no limit for the "waitUntil" event. What's the worst that could happen?

I think the biggest concern to "zombie service workers" would be using up resources for something the user doesn't want. The fetch API would let a service worker make unwanted or even malicious HTTP requests. Runtime cycles could be used to mine Bitcoins. Dumb service workers could use CPU cycles without any real reason. In aggregate, this could definitely make it possible for even benign service workers to become resource hogs. Most modern browsers already have methods to prevent tabs from using too many resources and those could apply here as well. However, I think it still needs to be considered that a bad yet fully compliant implementation of this spec _as currently written_ could enable some malicious service workers. Of course, this isn't anything that isn't possible in a normal JavaScript context- it's just much more powerful when they can live past all associated clients.

Although I still like my original "save-on-exit" use case, I'm thinking now that it would enable malicious use. Would it be possible to require that browsers clear the "extendLifetimePromises" array when all of a service workers associated clients are terminated?

@owencm
Copy link

owencm commented Aug 16, 2015

I think this usage of SW is actually not a good long term approach. SWs in general may not (and many would argue should not) live beyond the lifecycle of the final tab associated with that origin. I think this use case should probably be solved with something like the proposed Background Sync API (https://github.com/slightlyoff/BackgroundSync)

@wanderview
Copy link
Member

The defining feature of service workers is arguably that they can live without an active browsing context. An arbitrary "kill the SW if the browsing context goes away" rule seems to fly in the face of this design.

I suppose a UA could decide to terminate a fetch event or message event .waitUntil() if the browsing context goes away, though. Another event, like push, may still be holding the service worker alive, though, so its not a guarantee of stopping the script.

@jakearchibald
Copy link
Contributor

The SW may be killed when the last client goes away & the SW is not processing any other events that allow it to remain open (push, background sync).

Background sync is for background tasks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants