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

Comments

@n8schloss
Copy link

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

This comment has been minimized.

Copy link

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

This comment has been minimized.

Copy link
Contributor

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

This comment has been minimized.

Copy link
Contributor

commented Apr 4, 2017

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

@slightlyoff

This comment has been minimized.

Copy link
Contributor

commented Apr 4, 2017

self.registration.self?

@publicocean0

This comment has been minimized.

Copy link

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

This comment has been minimized.

Copy link
Member

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

This comment has been minimized.

Copy link
Author

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

This comment has been minimized.

Copy link

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

This comment has been minimized.

Copy link
Author

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

This comment has been minimized.

Copy link

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

This comment has been minimized.

Copy link
Author

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

This comment has been minimized.

Copy link
Member

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

This comment has been minimized.

Copy link

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

This comment has been minimized.

Copy link
Member

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

This comment has been minimized.

Copy link
Collaborator

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

This comment has been minimized.

Copy link
Member

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

This comment has been minimized.

Copy link
Collaborator

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

This comment has been minimized.

Copy link
Member

commented Jun 15, 2017

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

@NekR

This comment has been minimized.

Copy link

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

This comment has been minimized.

Copy link
Contributor

commented Nov 3, 2017

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

@jakearchibald

This comment has been minimized.

Copy link
Contributor

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

This comment has been minimized.

Copy link
Contributor

commented Nov 3, 2017

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

@jakearchibald

This comment has been minimized.

Copy link
Contributor

commented Nov 3, 2017

Previous discussion of exposing client IDs to the client #643

@jakearchibald

This comment has been minimized.

Copy link
Contributor

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

This comment has been minimized.

Copy link
Contributor

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

This comment has been minimized.

Copy link
Contributor

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

This comment has been minimized.

Copy link

commented Jun 20, 2019

LGTM, thank you for doing this!

@youennf

This comment has been minimized.

Copy link

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
10 participants
You can’t perform that action at this time.