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

Find a way for service workers to get their current state #1077

Closed
n8schloss opened this issue Feb 21, 2017 · 29 comments · Fixed by #1426
Closed

Find a way for service workers to get their current state #1077

n8schloss opened this issue Feb 21, 2017 · 29 comments · Fixed by #1426
Assignees
Milestone

Comments

@n8schloss
Copy link

@n8schloss n8schloss commented Feb 21, 2017

A service worker instance currently has no way to get it's current lifecycle state. There's a bit of a hack one can do where you keep track of the current event as a global variable but that's error prone and doesn't capture the waiting periods correctly.

Imo, the best way to solve this would be to just allow a service worker to get it's ServiceWorker object somehow. Maybe via self.worker or self.self or something like that.

@publicocean0
Copy link

@publicocean0 publicocean0 commented Feb 26, 2017

It is similar to my issue but I asked to use the same service worker as listener . I want notify my server when I can push a event and when a event can t be notified because no service worker is avaible to receive a notification

@jakearchibald jakearchibald added this to the Version 2 milestone Mar 30, 2017
@jakearchibald
Copy link
Contributor

@jakearchibald jakearchibald commented Mar 30, 2017

self.<something> to reference the current worker sounds like a good idea to me. Throwing self.thisServiceWorker into the bikeshedding ring, although it's a bit long.

@jakearchibald
Copy link
Contributor

@jakearchibald jakearchibald commented Apr 4, 2017

F2F: self.thisServiceWorker sounds good, unless anyone can come up with better

@slightlyoff
Copy link
Contributor

@slightlyoff slightlyoff commented Apr 4, 2017

self.registration.self?

@publicocean0
Copy link

@publicocean0 publicocean0 commented Apr 4, 2017

it is past a lot of time ago when i wrote about this problem .... if i remember correctly in my case i was searching a listener inside the service for all the states of service worker. My idea it was a bit advanced , a bit more for actual html5 :). Service worker is designed with many problems :

  • impossible to trace when browser starts up/is closing. Service worker life cicle might simulate to start when the browser is starting and closing as a real service (a kind of daemon in linux) even if it is running really just when a event is executed ;
  • impossible to wake up connections (web socket for example) or being triggered by on message event (the main scope of a service in computer science is to execute background code without user interation and to intercept async events from external universe. No ones of them is present in service worker)
  • service worker might simulate completely a service : a kind of process working independently by user interation ... instead it is pratically bind to the user interation.
    Service worker might be redesigned extending all the missing parts. Too much simple model when it might more complex and too much complex for solving simple things.

@wanderview
Copy link
Member

@wanderview wanderview commented Apr 6, 2017

If we stick this on ServiceWorkerRegistration we then have an attribute that is always unpopulated in other contexts.

I would also note we have another issue somewhere about referencing the current global as a Client, which is similar to this. Might be nice to make the naming be similar for the two concepts.

Maybe something like self.asServiceWorker and self.asClient()?

interface WindowOrWorker
{
  // returns a new snapshot
  Client asClient();
};

interface ServiceWorkerGlobalScope
{
  [SameObject]
  readonly attribute ServiceWorker asServiceWorker;
};

@n8schloss
Copy link
Author

@n8schloss n8schloss commented Apr 7, 2017

I totally agree that sticking this on the registration could get messy. self.asServiceWorker makes a lot of sense to me, so +1 for that :)

@delapuente
Copy link

@delapuente delapuente commented Apr 12, 2017

Since this is a source of confusion, I would be extra explicit when naming this member. I like @wanderview solution but what about .runningServiceWorker and .runningClient. Using the asXXX formula seems to mean like a sort of casting on the ServiceWorkerGlobalScope.

@n8schloss
Copy link
Author

@n8schloss n8schloss commented Apr 17, 2017

@delapuente you can have more than one SW instance running at a time, in this case we want the current context, not a currently running SW. @wanderview's suggestion makes more sense imo.

@delapuente
Copy link

@delapuente delapuente commented Apr 18, 2017

Can you? I thought you could only have one executing service worker at a time. With executing I mean running JavaScript code. I thought you could have several service workers in different states at the same time (installing, activating, active...) but only one running at a time. I mean without real parallelism.

If this is not the case, and since I continue thinking asXXX evoke a casting action, I believe the metaphor is well enough.

@n8schloss
Copy link
Author

@n8schloss n8schloss commented Apr 19, 2017

Alright, how about we just go with self.thisServiceWorker then as was suggested at the F2F? That seems to be the most clear.

@wanderview
Copy link
Member

@wanderview wanderview commented Apr 19, 2017

With executing I mean running JavaScript code. I thought you could have several service workers in different states at the same time (installing, activating, active...) but only one running at a time. I mean without real parallelism.

This is not accurate. You can have multiple service workers in different states and executing in separate threads simultaneously. Consider an installing worker handling its install event in parallel with the active worker handling fetch events from current page.

@delapuente
Copy link

@delapuente delapuente commented Apr 21, 2017

Thank you for the clarification, @wanderview

In that case, the spec says:

A ServiceWorkerGlobalScope object represents the global execution context of a service worker. A ServiceWorkerGlobalScope object has an associated service worker (a service worker).

So, I'm happy with self.serviceWorker and self.client or self.thisServiceWorker and self.thisClient (sounds weird) or, following spec terminology, self.associatedServiceWorker (sounds even weirder) and self.associatedClient.

@wanderview
Copy link
Member

@wanderview wanderview commented Jun 13, 2017

Note, if we do this we will need to also fix #1162. Currently a script cannot access its state at script evaluation time, but with the changes discussed here it might be possible. In that case we will need to expose the initial parsed state that occurs before the worker enters the installing state.

@jungkees
Copy link
Collaborator

@jungkees jungkees commented Jun 14, 2017

Note, if we do this we will need to also fix #1162.

Good catch. I think we can set the initial value of the state attribute to "parsed".

For the naming, I give my five cents to self.serviceWorker and self.client. this.serviceWorker sounds better than this.thisServiceWorker to me.

One more thing is what we'd expect postMessage() to self will do? Throwing an InvalidStateError? If the use case posed in the OP is about just exposing the state of itself, adding self.state (and probably self.onstatechange too) would be an option here?

@wanderview
Copy link
Member

@wanderview wanderview commented Jun 14, 2017

For the naming, I give my five cents to self.serviceWorker and self.client. this.serviceWorker sounds better than this.thisServiceWorker to me.

I see your reasoning here, but do you think it would be confusing if both of these were true:

'ServiceWorker' in self
'serviceWorker' in self

One is the webidl interface and the other is an instance of that interface. Single character differences in global names seems a bit dangerous to me.

@jungkees
Copy link
Collaborator

@jungkees jungkees commented Jun 15, 2017

I think we already have such a case in ServiceWorkerGlobalScope:

'Clients' in self
'clients' in self

But I understand your point, and it would prevent devs from using serviceWorker as a variable name on global scope.

@wanderview
Copy link
Member

@wanderview wanderview commented Jun 15, 2017

Yea, we also already have self.Performance and self.performance. I guess there is plenty of precedent.

@NekR
Copy link

@NekR NekR commented Jun 15, 2017

@wanderview almost every single one which is exposed on global object: window/Window (not in worker ofc), indexedDB/IndexedDB, etc. Not really a concern, first thing JS devs are taught is variables naming :-)

@jakearchibald
Copy link
Contributor

@jakearchibald jakearchibald commented Nov 3, 2017

I'm less bothered about self.ServiceWorker vs self.serviceWorker, but more bothered about serviceWorker vs navigator.serviceWorker.

@jakearchibald
Copy link
Contributor

@jakearchibald jakearchibald commented Nov 3, 2017

We might want to think about this in relation to #1036 – what would be the difference between a ServiceWorker, and a client representing a service worker?

If this turn out to be the same thing (or are merged somehow), clients.self() could be the answer.

@jakearchibald
Copy link
Contributor

@jakearchibald jakearchibald commented Nov 3, 2017

Or clients.selfId, which could be passed to clients.get().

@jakearchibald
Copy link
Contributor

@jakearchibald jakearchibald commented Nov 3, 2017

Previous discussion of exposing client IDs to the client #643

@jakearchibald
Copy link
Contributor

@jakearchibald jakearchibald commented Jun 12, 2019

Spec change #1426

Tests web-platform-tests/wpt#17285

I went with self.serviceWorker. If anyone wants to do some last-minute bikeshedding, now's the time 😀

@jakearchibald
Copy link
Contributor

@jakearchibald jakearchibald commented Jun 12, 2019

@aliams @asutherland @youennf @cdumez I believe there was agreement for this feature at the F2F, but I'd like to be sure.

TL;DR: New feature: In a service worker, self.serviceWorker gives you a service worker instance for this service worker.

So, if you wanted to know what state this service worker was in, you'd read self.serviceWorker.state.

Are you happy for me to land this change?

@jakearchibald
Copy link
Contributor

@jakearchibald jakearchibald commented Jun 20, 2019

@asutherland @youennf @cdumez nudge. Pretty sure we agreed on this at the f2f, but I don't want to land this without double checking.

@asutherland
Copy link

@asutherland asutherland commented Jun 20, 2019

LGTM, thank you for doing this!

@youennf
Copy link

@youennf youennf commented Jun 21, 2019

LGTM too

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

Successfully merging a pull request may close this issue.

10 participants