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

consider firing a "clientcontrolled" event on ServiceWorkerGlobalScope #886

Open
wanderview opened this Issue Apr 21, 2016 · 8 comments

Comments

Projects
None yet
4 participants
@wanderview
Copy link
Member

wanderview commented Apr 21, 2016

I'd like to tentatively propose that we fire a clientcontrolled event on the ServiceWorkerGlobalScope when that worker begins controlling a client. There could also be a clientuncontrolled event, but that is less important to me at the moment.

This could enable service workers to maintain and track state more specifically than they can do today. Right now SWs can infer which clients are going to be controlled from FetchEvent, but its really an approximation. Some documents will fail to load or be closed. Exposing these events would provide better tracking.

My real reason for suggesting this, though, is to handle a corner case with bfcache. I realize firefox might be the only browser to implement bfcache, so this may not be a strong argument. But consider the following situation:

  1. Document A is controlled by SW X.
  2. User navigates the window and A goes into the bfcache. A also becomes uncontrolled at this point so history items don't block updates, etc.
  3. SW X then does a Clients.matchAll() and see A is gone. It cleans up Cache objects and state A was using.
  4. User clicks the back button and A comes back out of the bfcache. Our current plan is to make it controlled again with the same client ID.
  5. SW X does a Clients.matchAll() and suddenly sees A again, but it never saw a FetchEvent. SW becomes confused and goes to cry in the corner.

Some options we considered, but currently don't like:

  • Disable bfcache for documents that are controlled. This would effectively disable bfcache for huge swaths of the internet; Facebook, Pinterest, etc.
  • Expose documents in bfcache to Clients.matchAll(). This would be super confusing as the list just grows as the user navigates. Also, things like Client.focus() would not make sense.
  • Don't re-control documents when they come out of bfcache. This would make it look like a new uncontrolled client appeared which is normally possible via a hard refresh. This would expose a difference between browsers, though, because history.back() would result in a controlled document in chrome, but not firefox.

I'm open to suggestions, but the clientcontrolled event would have wider application and would let the SW behave sensibly to this case.

@jakearchibald jakearchibald modified the milestones: Version 1, Version 2 Jul 25, 2016

@jakearchibald

This comment has been minimized.

Copy link
Collaborator

jakearchibald commented Jul 29, 2016

Pre F2F notes: Let's make sure we have all the use cases here. Do we need clientuncontrolled? Realise that's been avoided in the past with sharedworker.

@wanderview

This comment has been minimized.

Copy link
Member

wanderview commented Aug 1, 2016

I think something like clientuncontrolled is harder with SharedWorker since its lifecycle is tied to the GC of the attached documents. In ServiceWorker case controller state is tied to window activity. So it becomes uncontrolled when the window is closed or iframe.remove() happens.

I'm not sure about worker clients, though. Those might still be based on GC.

@annevk

This comment has been minimized.

Copy link
Member

annevk commented Aug 4, 2016

I'm not really convinced we understand the lifetime of a window well enough though. E.g., when you navigate the previous window can still be there in some form. Is there a clear enough action in HTML (that is implemented as such too) we can tie this too?

@wanderview

This comment has been minimized.

Copy link
Member

wanderview commented Aug 4, 2016

Service worker control is tied to "active" documents and windows AFAICT. We are pretty consistent in wpt tests in expecting frame.remove() to no longer be controlled. In addition, we already have to deal with no longer controlling documents in the bfcache, etc.

Whether we have the right text in the spec or not, I don't know. But it is happening today.

@asutherland

This comment has been minimized.

Copy link

asutherland commented Aug 4, 2016

It looks like document client-wise, 7.8.10 History Traversal's step 3 Make entry's Document object the active document of the browsing context. can correspond to "clientcontrolled", it just needs an "other applicable specifications" algorithm callout here. This covers:

For "clientuncontrolled", it seems like unload a document is already linked in appropriately. Specifically, Handle Service Worker Client Unload's "unloading" link links to HTML's unload a document and we can add a step in the SW spec there already. (HTML's unload a document Step 10 explicitly says Run any unloading document cleanup steps for Document that are defined by this specification and other applicable specifications. The only reason one might want a change is if we want the parent document to notify ahead of its iframes; those get unloaded in step 13.)

@annevk

This comment has been minimized.

Copy link
Member

annevk commented Aug 5, 2016

I suspect we want "fully active" documents, not just active. Still, there's a whole bunch of things around the lifecycle of documents that is not interoperable.

@jakearchibald

This comment has been minimized.

Copy link
Collaborator

jakearchibald commented Nov 8, 2017

F2F: clientcontrolled is more important than clientuncontrolled. clientuncontrolled may be unwanted, as it involves spinning something new up, when we're wanting to tear down a process.

@wanderview

This comment has been minimized.

Copy link
Member

wanderview commented Dec 16, 2017

Here are some other cases where a clientcontrolled event would be useful. Currently we can create controlled clients without a FetchEvent in a number of ways:

  1. about:blank or about:srcdoc iframes inheriting the controller from its parent
  2. blob: URL frames and workers
  3. document.open() creates a new global and inherits the controller like about:blank frames (currently only implemented in firefox, but the spec agrees)

Edit: Note, in Firefox 58 and earlier we did not change the client id on document.open() even though we replaced the global. We were incorrectly tying the client to the document. In Firefox 59 we start minting a new client id to reflect the new global.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment