-
Notifications
You must be signed in to change notification settings - Fork 315
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
Does changing updateViaCache mint a new ServiceWorkerRegistration or update them all? #1189
Comments
(The spec doesn't seem to address this, we get to "Invoke Update algorithm passing job as the argument" but nothing there updates updateViaCache AFAICT) |
Good catch. The other properties are live, so it'd be confusing to make other properties a snapshot. We could add const { updateViaCache } = await reg.getState(); |
We only just recently landed this in firefox nightly. There I think you will get:
I think this behavior is determined by step 5.3 here in the spec: https://w3c.github.io/ServiceWorker/#register-algorithm You should skip the short-circuit because the cache mode is different and get a new registration. EDIT: This comment is wrong... |
And the update algorithm gets the cache mode out of the newest worker in step 3 and step 7.2 here: https://w3c.github.io/ServiceWorker/#update-algorithm So I'm not sure I understand the particular problem here. Edit: This comment is wrong... |
Errr... my last comment makes no sense because I think changing the |
In firefox we change the http://searchfox.org/mozilla-central/source/dom/workers/ServiceWorkerRegisterJob.cpp#42 We didn't deal with exposing it on the worker thread yet because there are lots of things we already do not expose there. I agree we need a spec change somewhere here. |
Putting updateViaCache on the registration seems fine to me. We're registering or updating a registration's state. So, such processes using the last value of the registration seems good. If it had been on each service worker, the values used for the installation of existing workers wouldn't have been changed anyway. I think this property should be live as the other properties though. The spec currently doesn't update the value in Update algorithm, but I think the value should be updated by referencing job's update via cache mode before fetching. The expected behavior that I think of is: var reg = await navigator.serviceWorker.getRegistration(url);
reg.updateViaCache; // 'all';
var r = await register(sw, {updateViaCache: 'none'});
reg === r; // true
reg.updateViaCache; // 'none'
r.updateViaCache; // 'none' I think the update via cache mode isn't part of the identity of a registration but just a strategy clients set. WDYT? |
Do we have other persistent state on the service worker that is mutable without installing a new service worker? I don't think we do right now. |
Also, I find it weird that |
No. Not until updating. My point was adding that info to a service worker instead of a registration wouldn't be more useful.
Interesting. It seems you think of a JS registration object a thing that represent the state of the underlying registration struct. I think we discussed this a way back and settled on the behavior the JS objects for the same registration struct pass equality check. And the registration object's attribute getters return the latest values set by register/update operations. The current implementations reflect that behavior, right? |
Well there is the navigation preload state that can be mutated. Yes ServiceWorkerRegistration objects representing the same registration entity pass the JS equality check (assuming they're from the same document/worker context, otherwise they are not equal due to different prototypes). I'm not sure about creating a new registration just for the updateViaCache change. I'd find it surprising for ServiceWorkerGlobalScope#registration to change over the lifetime of a the service worker. |
You would get a new service worker version with the new registration. So this would not happen.
True, but AFAICT that state is not set as part of a FWIW, though, we are currently planning to ship the behavior in #1189 (comment) in FF57. I feel like this is a bit of a corner case, so I think we can change it later as long as we maintain an |
Maybe we should discuss at TPAC. FWIW, my personal preference here would be to try to treat all values passed to Edit: And I would prefer to move @jakearchibald do you have an opinion on this from a developer ergonomics point of view? |
Good topic for TPAC :)
Just to confirm, suppose there is an active worker
Ah this might be key. In Chromium script URL is just a property on the service worker. So a registration can have multiple script URLs. We don't mint a new registration when you register a worker with a different script URL to the newest worker:
|
Right. You get a new ServiceWorker with the new scriptURL, not a new registration. I think I want updateViaCache to work the same way. Since I've been so confused on this issue I'm going to write a glitch to see what we currently have implemented. |
Ok, so I'm just completely wrong and should probably go jump in a lake. We do what @jungkees suggested in #1189 (comment). I wrote a glitch to test what we currently do: https://sw-change-updateviacache.glitch.me/ Which on current firefox nightly 57 produces:
So we don't create a new registration. We also don't create a new ServiceWorker. Looking at our code, though, I do think we trigger an update check at this point. We don't do the short circuit, but our update doesn't find any changes and just keeps the current service worker. |
My aim with this stuff is to try and reduce the amount of independently-set state as much as possible. This means if you update your call to My worry with something like I wanted to do something similar with navigation preload, where you'd have to declare it per service worker instance (in the install or activate event), but we lost the ability to do that when we gained additional state – the header value. The service worker registration object is already "live", since When the registration changes, we already update registration objects if it results in a new If so, I'm happy to look at a |
My implementor feedback is that it's not a big problem. If it makes sense from the ergonomics POV I support doing it this way. Of course async getState() would probably be simpler to implement, but you're right that we already do the live update for active/waiting/installing. |
Just to clarify, we do trigger an immediate update check if updateViaCache is changed. Another glitch with a timestamp service worker script: https://sw-change-updateviacache-with-update.glitch.me/ Gives:
I think this is reasonable to do, but not sure if it should be required by the spec. |
I see Firefox 57 is shipping updateViaCache. It sounds like the basic behavior is: when only updateViaChanges changes, don't mint a new ServiceWorkerRegistration or a new ServiceWorker (unless the byte-for-byte content changed), and ServiceWorkerRegistration#updateViaCache is a live property? Do we have spec language and WPT tests for this? registration-updateviacache.https.html doesn't seem to test ServiceWorkerRegistration equality. |
I don't think this case is tested by a WPT yet, no. Also, we have an issue where trying to access I think the correct long term for this access after unregister is just to return the last value cached on the DOM object. |
Thanks. Would be good to have spec language and WPT tests soon. Chrome is (still) trying to implement this. The behavior about not minting a new registration and making updateViaCache live sounds good to me. Checking updateViaCache after unregister seems pretty niche... either throwing or returning the last value sounds fine. |
If we are doing the "post a task to update the updateViaCache value on the right thread" thing, then I think just returning the last known value makes the most sense. The reason we are throwing is because we are implementing the live value by finding the registration when accessed (because we don't support access on worker threads yet). |
F2F: Keep same registration object, but update property value. |
https://bugs.webkit.org/show_bug.cgi?id=180888 Reviewed by Brady Eidson. LayoutTests/imported/w3c: Rebaseline WPT test now that more checks are passing. * web-platform-tests/service-workers/service-worker/registration-updateviacache.https-expected.txt: Source/WebCore: Support updating a service worker registration's updateViaCache flag to match other browsers: - w3c/ServiceWorker#1189 No new tests, rebaselined existing test. * workers/service/SWClientConnection.cpp: (WebCore::SWClientConnection::setRegistrationUpdateViaCache): * workers/service/SWClientConnection.h: * workers/service/ServiceWorkerRegistration.cpp: (WebCore::ServiceWorkerRegistration::setUpdateViaCache): * workers/service/ServiceWorkerRegistration.h: * workers/service/server/SWServer.h: * workers/service/server/SWServerJobQueue.cpp: (WebCore::SWServerJobQueue::runRegisterJob): * workers/service/server/SWServerRegistration.cpp: (WebCore::SWServerRegistration::setUpdateViaCache): * workers/service/server/SWServerRegistration.h: Source/WebKit: * StorageProcess/ServiceWorker/WebSWServerConnection.cpp: (WebKit::WebSWServerConnection::setRegistrationUpdateViaCache): * StorageProcess/ServiceWorker/WebSWServerConnection.h: * WebProcess/Storage/WebSWClientConnection.messages.in: git-svn-id: http://svn.webkit.org/repository/webkit/trunk@225992 268f45cc-cd09-0410-ab3c-d52691b4dbfc
We have consensus to make updateViaCache a live property, but no spec or WPT for that yet. Chrome is now implementing this. Would people be OK with us landing a WPT for it now (adding it to the existing registration-updateviacache test)? Or would you rather we not land WPT changes until the spec text is also updated? |
Just to clarify, by "live property" you mean updating a property on the binding object via a task, right? A WPT would be great. I actually implemented this behavior while refactoring some other things in gecko. See P9 of this bug shipping in FF60: https://bugzilla.mozilla.org/show_bug.cgi?id=1434701 Sorry I neglected to add a test at that time. |
I was a bit wrong. We have basic tests that the registration object remains the same and the updateViaCache property is updated after register() is called with a new value. I wanted to add a test that all registration objects for the same registration entity are updated. So the test would like:
I'm not sure when the spec guarantees that frameReg.updateViaCache is updated. So our test might use wait_for_activation_on_dummy_scope() to try to wait for the update to happen. I'd also like to add a test for the unregister() case, just to ensure we don't crash. We could do these as Chromium only tests since the spec might be vague here, but I prefer WPT tests by default. |
Sounds like a good WPT to me. FWIW, in gecko I'm updating it whenever we hit "update registration state": https://w3c.github.io/ServiceWorker/#update-registration-state-algorithm And I effectively added to step 5 in Register: https://w3c.github.io/ServiceWorker/#register-algorithm These steps:
Edit: One difference in gecko's "update registration state" is that we effectively sync the entire state there. We only fire statechange events and whatnot if something changes on the binding object. So we pretty much ignore the arguments passed. |
F2F: Need to update the spec for this. |
updateViaCache is a live property. WPT was added at https://github.com/web-platform-tests/wpt/blob/master/service-workers/service-worker/registration-updateviacache.https.html |
This makes the following changes: * updateViaCache is a live property. This is covered by the WPT registration-updateviacache.https.html. However we are missing tests for a register() that rejects with a new updateViaCache property. The desired behavior is to only update the property if register() resolves. * Changing worker type bypasses the byte-for-byte update check. This is covered by WPT update-registration-with-type.https.html. * Adds Worker type and updateViaCache to the job equivalence check. This probably can have a WPT for successive register() calls that vary these properties don’t get coalesced into a single job. Addresses w3c#1189, w3c#1408, w3c#1359, and w3c#1358.
…1411) This makes the following changes: * updateViaCache is a live property. This is mostly covered by the WPT registration-updateviacache.https.html. A test that the updateViaCache change is only committed if the register() call resolves is added in web-platform-tests/wpt#17131. * Changing worker type bypasses the byte-for-byte update check. This is covered by WPT update-registration-with-type.https.html. * Adds Worker type and updateViaCache to the job equivalence check. A test for this is added in web-platform-tests/wpt#17131. Addresses #1189, #1408, #1359, and #1358.
Addressed in #1411 |
Suppose you have something like this:
I'm leaning toward updating all existing ServiceWorkerRegistration objects, because otherwise ServiceWorkerGlobalScope#registration would have to mutate to a brand new registration object after register() settled, which doesn't feel right.
However, updating them all is a bit troublesome and seems to lead to race conditions (one of them has been updated but the others haven't). Would it be worth considering changing reg.updateViaCache to a promise similar to NavigationPreloadManager state?
@wanderview what does Firefox do?
The text was updated successfully, but these errors were encountered: