-
Notifications
You must be signed in to change notification settings - Fork 2.7k
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
Allow workers & shared workers to be created within a service worker #411
Comments
+@domenic as you've been looking into workers recently |
I guess I'd like to know how realistic it is that other browsers will implement this. As far as I know, gecko is the only browser that has implemented nested workers so far. |
Allowing SharedWorker access from ServiceWorkers would make it at lot more feasible to provide robust offline support with background sync. In any application with a non-trivial data model, it's pretty typical to layer business logic and caching on top of a raw data store like IDB. Without support for SharedWorkers, it's hard to provide a single source of truth to the applications UI components. Business logic will have to be duplicated between the ServiceWorker and SharedWorkers or UI processes, making it easy to introduce inconsistencies and race conditions. |
There is a rather sizable amount of discussion in w3c/ServiceWorker#756 where people seem to think the alternative to what is proposed at the top of the thread - spinning up multiple service workers to prevent blocking - is to have service workers call out to workers to perform work. And based on a twitter discussion, I think this not being the case violates a lot of people's expectations. An example use case could be w3c/ServiceWorker#744, where someone discusses using BPG image-format-decoding in a ServiceWorker. They ought be able to offload this work into a worker. |
I've thought about just moving ahead with this in Firefox since its not that hard to adapt our current nested worker code to SW. While it might see limited use without Chrome also implementing, it is easily feature detectable and could enable some niche applications to be better implemented. @jakearchibald How would you feel about us experimenting here? |
Of course, the html spec marks |
The part that isn't spec'd is how the lifetime of a worker would be tied to the lifetime of a service worker. Currently their lifetime is fully defined in terms of associated documents. |
Yeah, HTML already does its part here; per step 5 of https://html.spec.whatwg.org/multipage/workers.html#run-a-worker this is supported. But if we want to add something like terminating a worker when the service worker terminates, the service worker spec would need to add appropriate steps. |
Why wouldn't the Worker/SharedWorker GC when the ServiceWorker terminates handle that? Seems equivalent to me. Edit: Nevermind. I see how it explicitly uses Documents here: https://html.spec.whatwg.org/multipage/workers.html#the-worker's-lifetime |
Seems like all we need is:
|
I'm a little hesitant about exposing shared workers in more places without commitment from other browsers to support them in the first place. Exposing dedicated workers in service workers seems like a good thing though. |
@wanderview sounds like a good idea to me. The way you want to implement this sounds like what I proposed in the OP
|
#315 is about potentially removing shared workers. It seems we're still at a bit of a stalemate there, but hopefully Edge and Safari will come around. Then there are some other issues:
|
I thought it was implemented in Firefox? |
No, not per @bakulf yesterday at least:
|
Instead of each worker being owned by a document, have it instead be owned by one or more of its parents (more only in the case of SharedWorkerGlobalScope). This makes it possible to define JavaScript agent clusters (#2260) and also helps with allowing service workers to have nested workers (#411). This is marked editorial as it should have no normative impact. This also removes a step that should have been removed as part of 4e2b006 9418bd.
Instead of each worker being owned by a document, have it instead be owned by one or more of its parents (more only in the case of SharedWorkerGlobalScope). This makes it possible to define JavaScript agent clusters (#2260) and also helps with allowing service workers to have nested workers (#411). This is marked editorial as it should have no normative impact. This also removes a step that should have been removed as part of 4e2b006.
I have some long term plans to possibly replace SharedWorker owner with a primitive that essentially maps to the Client type (which in turn represents an environment). In our implementation this would then let the SharedWorker be owned by another Worker. (It would also buy us cross-process support, but that's less relevant here.) There might be some oddness with the about:blank replacement case, though. It could work out, though, if a SharedWorker object in use by the about:blank is just GC'd when the replacement happens. |
Okay, so the main todo items here are after #2520 lands:
|
Probably beating a dead horse now, but I thought of another reason to switch SharedWorker/DedicatedWorker owners to globals instead of documents. Consider:
Under the current spec language I'm not sure what would happen here. The SharedWorker DOM objects still exists, but the SharedWorker thread is treating the old about:blank document as its owner, not the new document in the iframe. If the SharedWorker treated the global as the owner then this would work cleanly. Under most use cases the SharedWorker DOM object will be GC'd with the document which will match current spec'd behavior. It also handles, however, this weird shared global case with about:blank replacement. |
Instead of each worker being owned by a document, have it instead be owned by one or more of its parents (more only in the case of SharedWorkerGlobalScope). This makes it possible to define JavaScript agent clusters (#2260) and also helps with allowing service workers to have nested workers (#411). This is marked editorial as it should have no normative impact. This also removes a step that should have been removed as part of 4e2b006.
One thing to think about when this is spec'd and implemented:
It seems we would need to do the same propagation of lifetime budget for nested workers that we do for self-postmessage. The fetch events from a nested worker solely owned by the service worker should not grant new lifetime budget to that service worker. As an added wrinkle, a shared worker could transition from being solely owned by the service worker to being shared with a window and back again. Should be fun to implement and test. |
I looked into the lifetime issue and it does seem like all user agents associated them with documents at the moment, given <script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<iframe></iframe>
<script>
async_test(t => {
const frame = self[0],
worker = new frame.Worker("pong.js")
worker.postMessage("hi")
worker.onmessage = t.step_func(e => {
if(e.data === "hi") {
alert("navigating...")
frame.frameElement.src = "/common/blank.html"
frame.frameElement.onload = t.step_func(() => {
worker.postMessage("navigated")
})
} else if(e.data === "navigated") {
alert("still alive")
}
})
})
</script> and onmessage = e => { postMessage(e.data) } I also tested removing the |
Instead of each worker being owned by a document, have it instead be owned by one or more of its parents (more only in the case of SharedWorkerGlobalScope). This makes it possible to define JavaScript agent clusters (whatwg#2260) and also helps with allowing service workers to have nested workers (whatwg#411). This is marked editorial as it should have no normative impact. This also removes a step that should have been removed as part of whatwg@4e2b006.
Instead of each worker being owned by a document, have it instead be owned by one or more of its parents (more only in the case of SharedWorkerGlobalScope). This makes it possible to define JavaScript agent clusters (whatwg#2260) and also helps with allowing service workers to have nested workers (whatwg#411). This is marked editorial as it should have no normative impact. This also removes a step that should have been removed as part of whatwg@4e2b006.
Instead of each worker being owned by a document, have it instead be owned by one or more of its parents (more only in the case of SharedWorkerGlobalScope). This makes it possible to define JavaScript agent clusters (whatwg#2260) and also helps with allowing service workers to have nested workers (whatwg#411). This is marked editorial as it should have no normative impact. This also removes a step that should have been removed as part of whatwg@4e2b006.
Any more news on this? |
Closing this as nothing much happened since #5601 and the specification now reflects reality. If someone still thinks we should do this use cases and such would help, ideally in a new issue. |
FWIW I still think we should do this and will write a new issue when I am ready to work on it. |
@wanderview did you have time to have a look at this? |
As chrome extensions migrate to manifest v3, background scripts become service workers. Since chrome extensions cannot reliably spawn web workers from content scripts (due to potential CSP restrictions in the host page), it'd be very useful to be able to spawn web workers from the chrome extension's service worker to execute some WASM. Created a new issue to track this use case as requested by @annevk above: #8362 |
At the moment, a (shared)worker's lifecycle is linked to related documents, but these should be creatable within a service worker to do things such as image processing, expensive diffing etc without locking up the service worker.
I imagine this means changing the worker's documents to be the worker's clients, where clients can be documents or service workers.
Previous discussion w3c/ServiceWorker#678
The text was updated successfully, but these errors were encountered: