-
Notifications
You must be signed in to change notification settings - Fork 313
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
"Unregister" operation may be interrupted by ServiceWorker#postMessage
#1146
Comments
Thanks for reviewing to this detail. Unregister algorithm being invoked means the update job is scheduled and run. So, we set the uninstalling flag to not allow getting this registration or running any action on it from this point. (Only a scheduled register job can flip this.) Also, we try to clear registration at the earliest possible (via Try Clear Registration in many points where the registration's workers are idle.) But as you pointed, we missed this right within the Unregister algorithm itself. I think we should invoke Try Clear Registration before invoking Resolve Job Promise. That'll make the resolve task will be scheduled after the tasks that mutate the states. Then, the unregister() promise's settlement callbacks when scheduled will see the active worker became redundant. So, I think the expected behavior here should be postMessage() throw an "InvalidStateError". WDYT? |
I don't think we can safely call Try Clear Registration from the thread calling unregister(). The state checks in Try Clear Registration is managed on a different thread. Also, I'm not sure it would be correct if you consider the different ways a register job could also be queued. We probably just need algorithms to handle the uninstalling flag. For postMessage() it should probably just eat the message silently as thats what we do when you postMessage a closing window. For other things we may want to throw an error. We could also add text saying the UA should not start a new SW thread for a registration with the uninstalling flag set. |
Try Clear Registration insn't called from the thread calling unregister(). It's called from a thread scheduling the job queue. Also, since we're updating the states from queued tasks (Update Worker State, Update Registration State), I don't see a problem maintaining the order of changing the states.
I'm not seeing a problem here. Let's say a register job R is queued after an unregister job Un. If the Try Clear Registration from Un triggered Clear Regirstration as the registration was totally idle, R won't find the registration in its execution later in the first place. Else if the Try Clear Registration from Un just returned without invoking Clear Registration, R will unset the registration's uninstalling flag.
postMessage() to an uninstalling registration's worker (as in the OP example) throwing early sounds more reasonable to me. For other things, e.g. for getRegistration(), Match Service Worker Registration, not returning the result while uninstalling flag is set sounds very reasonable to me too. In my mental model, calling unregister() means I expect no further actions to the registration should happen but admit that I should wait until other clients are all being served.
I think this is a good idea. We can add a condition in the begining of Run Service Worker to not allow starting a thread if the given worker's registration is uninstalling. |
I really don't want to alter state outside of the job queue. We used to do that and it had so many race conditions. I think we should work with the uninstalling flag as the given signal. I'm not sure what the semantics of various calls should be. We should probably talk to @jakearchibald or other web devs about that. Maybe this would be a good one to discuss in person at next meeting. |
Hmm.. I think I got you. The Try Clear Registration initiated from unregister() is called in the At least, all of the them check if the registration's uninstalling flag is set before they invoke Try Clear Registration. But that's not enough to avoid them race, right?
Could you get a little more specific on this? I'd like to think about this option together.
Surely though I hope we can find a resolution even before that. |
I think those places are mostly right for checking the installing flag. The steps that call them probably need to be executed on the thread managing the job queue, though. Right now they are on the worker thread in the spec.
I was just saying methods on the ServiceWorker and ServiceWorkerRegistration objects can probably check the uninstalling flag in order to trigger any "don't allow this on an uninstalling service worker" logic. Another perspective, though, is that as long as a page has the ServiceWorker DOM object referenced and the service worker is not in the redundant state, then the methods on that object should work. Maybe we should permit postMessage() in this case. If something is listed as With that approach we would base the "don't allow this on an uninstalling service worker" based on the service worker's state (redundant, etc). This would be the least racy, but would allow postMessage() while waiting for the active worker to go idle. This is where I'm not sure what semantics make most sense for developers. |
For this particular issue I'm thinking:
There are some related issues here like whether postMessage() should block on Run Service Worker (mentioned in #1403 ) and we generally don't really check to see if Run Service Worker failed (with the exception of the Update algorithm). I'm not sure if the spec changed since the discussion on this thread, but using the registration's uninstalling flag for this doesn't seem right... we set the flag in unregister() but the service worker is still alive and usable while it has clients (so it can stop and be restarted multiple times). |
I feel like postMessage() throwing is somewhat unexpected. For example, we don't do that in cases where the other end of MessageChannel is gone. I would be more in favor of sending the message to /dev/null, maybe with a console warning. |
That's a fair point. I guess silent-failing is at least consistent. |
SGTM. |
…workers. (#1419) This cleans up Run Service Worker to block until the worker is running or fails to start. Callsites are updated to check if the worker is running before proceeding. It also disallows starting a redundant worker. postMessage is dropped silently if starting the service worker failed. Addresses #1146 and #1403.
Addressed in #1419. |
Update the WPT and fix behavior. Per spec change at w3c/ServiceWorker#1146. Bug: 972461 Change-Id: Id4bac3fbe1996382952e54d46cb405de9eb951b3
Update the WPT and fix behavior. Per spec change at w3c/ServiceWorker#1146. Bug: 972461 Change-Id: Id4bac3fbe1996382952e54d46cb405de9eb951b3 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1650685 Reviewed-by: Hayato Ito <[email protected]> Reviewed-by: Kenichi Ishibashi <[email protected]> Commit-Queue: Matt Falkenhagen <[email protected]> Cr-Commit-Position: refs/heads/master@{#667523}
Update the WPT and fix behavior. Per spec change at w3c/ServiceWorker#1146. Bug: 972461 Change-Id: Id4bac3fbe1996382952e54d46cb405de9eb951b3 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1650685 Reviewed-by: Hayato Ito <[email protected]> Reviewed-by: Kenichi Ishibashi <[email protected]> Commit-Queue: Matt Falkenhagen <[email protected]> Cr-Commit-Position: refs/heads/master@{#667523}
Update the WPT and fix behavior. Per spec change at w3c/ServiceWorker#1146. Bug: 972461 Change-Id: Id4bac3fbe1996382952e54d46cb405de9eb951b3 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1650685 Reviewed-by: Hayato Ito <[email protected]> Reviewed-by: Kenichi Ishibashi <[email protected]> Commit-Queue: Matt Falkenhagen <[email protected]> Cr-Commit-Position: refs/heads/master@{#667523}
…dundant workers silently., a=testonly Automatic update from web-platform-tests service worker: Drop postMessage() to redundant workers silently. Update the WPT and fix behavior. Per spec change at w3c/ServiceWorker#1146. Bug: 972461 Change-Id: Id4bac3fbe1996382952e54d46cb405de9eb951b3 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1650685 Reviewed-by: Hayato Ito <[email protected]> Reviewed-by: Kenichi Ishibashi <[email protected]> Commit-Queue: Matt Falkenhagen <[email protected]> Cr-Commit-Position: refs/heads/master@{#667523} -- wp5At-commits: 0ea1346335e30ab897ee5124aeeafcae663b5f49 wpt-pr: 17246
…dundant workers silently., a=testonly Automatic update from web-platform-tests service worker: Drop postMessage() to redundant workers silently. Update the WPT and fix behavior. Per spec change at w3c/ServiceWorker#1146. Bug: 972461 Change-Id: Id4bac3fbe1996382952e54d46cb405de9eb951b3 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1650685 Reviewed-by: Hayato Ito <[email protected]> Reviewed-by: Kenichi Ishibashi <[email protected]> Commit-Queue: Matt Falkenhagen <[email protected]> Cr-Commit-Position: refs/heads/master@{#667523} -- wp5At-commits: 0ea1346335e30ab897ee5124aeeafcae663b5f49 wpt-pr: 17246
Update the WPT and fix behavior. Per spec change at w3c/ServiceWorker#1146. Bug: 972461 Change-Id: Id4bac3fbe1996382952e54d46cb405de9eb951b3 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1650685 Reviewed-by: Hayato Ito <[email protected]> Reviewed-by: Kenichi Ishibashi <[email protected]> Commit-Queue: Matt Falkenhagen <[email protected]> Cr-Commit-Position: refs/heads/master@{#667523}
…dundant workers silently., a=testonly Automatic update from web-platform-tests service worker: Drop postMessage() to redundant workers silently. Update the WPT and fix behavior. Per spec change at w3c/ServiceWorker#1146. Bug: 972461 Change-Id: Id4bac3fbe1996382952e54d46cb405de9eb951b3 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1650685 Reviewed-by: Hayato Ito <hayatochromium.org> Reviewed-by: Kenichi Ishibashi <bashichromium.org> Commit-Queue: Matt Falkenhagen <falkenchromium.org> Cr-Commit-Position: refs/heads/master{#667523} -- wp5At-commits: 0ea1346335e30ab897ee5124aeeafcae663b5f49 wpt-pr: 17246 UltraBlame original commit: 5212e992eae1bd2c5c287946cd79bd489b9cba27
…dundant workers silently., a=testonly Automatic update from web-platform-tests service worker: Drop postMessage() to redundant workers silently. Update the WPT and fix behavior. Per spec change at w3c/ServiceWorker#1146. Bug: 972461 Change-Id: Id4bac3fbe1996382952e54d46cb405de9eb951b3 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1650685 Reviewed-by: Hayato Ito <hayatochromium.org> Reviewed-by: Kenichi Ishibashi <bashichromium.org> Commit-Queue: Matt Falkenhagen <falkenchromium.org> Cr-Commit-Position: refs/heads/master{#667523} -- wp5At-commits: 0ea1346335e30ab897ee5124aeeafcae663b5f49 wpt-pr: 17246 UltraBlame original commit: 5212e992eae1bd2c5c287946cd79bd489b9cba27
…dundant workers silently., a=testonly Automatic update from web-platform-tests service worker: Drop postMessage() to redundant workers silently. Update the WPT and fix behavior. Per spec change at w3c/ServiceWorker#1146. Bug: 972461 Change-Id: Id4bac3fbe1996382952e54d46cb405de9eb951b3 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1650685 Reviewed-by: Hayato Ito <hayatochromium.org> Reviewed-by: Kenichi Ishibashi <bashichromium.org> Commit-Queue: Matt Falkenhagen <falkenchromium.org> Cr-Commit-Position: refs/heads/master{#667523} -- wp5At-commits: 0ea1346335e30ab897ee5124aeeafcae663b5f49 wpt-pr: 17246 UltraBlame original commit: 5212e992eae1bd2c5c287946cd79bd489b9cba27
Consider the following code:
"unregistration" involves the following sequence:
true
state
attribute of the active worker to"redundant" (via Update Worker State)
active
property tonull
(via Update Registration State)
This means the
state
attribute is not set until after the promise has beenresolved and any subsequent microtasks processed. Here, the
postMessage
invocation is part of such a microtask, so when it references the worker's
state
, it receives the value "active". Execution of thepostMessage
algorithm proceeds to step 4, where Run Service Worker is invoked. This creates
a new ServiceWorkerGlobalScope object, effectively undoing the prior invocation
of Terminate Worker.
Chromium's behavior more or less adheres to this interpretation, although the
worker's script is only evaluated one time (I would expect a second evaluation
for that invocation of Run Service Worker). Firefox throws an error named
NS_ERROR_FAILURE
from thepostMessage
invocation. In either case, thisseems like a spec bug--the "unregister" operation is being interrupted, but the
worker state is still ultimately set to "redundant."
Distinguishing between "user-requested un-registration" and "user-agent
requested termination" seems necessary in order to decide whether to throw or
re-start the worker. Making this determination may not be possible from an
arbitrary
postMessage
invocation without the introduction of additionalstate or a modification to the schedule of operations in Clear Registration.
The text was updated successfully, but these errors were encountered: