-
-
Notifications
You must be signed in to change notification settings - Fork 504
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
Chrome unregisters MSW after 5 mins of inactivity / idle #2115
Comments
Hi, @jkinger. Thanks for reporting this. Looks like Chrome has changed the way it deactivates idle service workers. We have a ping/pong messaging in place to make sure the client constantly messages the worker so it never goes idle: msw/src/browser/setupWorker/start/createStartHandler.ts Lines 85 to 88 in ad8ebac
Lines 42 to 47 in ad8ebac
Previously, the worker was considered idle if it hasn't handled any messages in the N period of time. Now, it looks like the criteria for that changed. |
Extension Service Worker termination policy changeI can see that Google has changed the Service Worker termination rules for Service Workers in extensions:
This should have no effect on MSW as it's not an extension but a Service Worker registered by your app. |
Chrome FAQ on Service Worker terminationI've found another mention of this behavior that doesn't seem to be related to extension Service Workers but generally to Service Workers in Chrome:
If this is true, then the idle period has shortened from 5 minutes to 30 seconds. It's worth mentioning this is a behavior specific only to the Manifest V3 API. Perhaps that's why it's not surfacing for everyone? |
I wonder why Chrome doesn't do this to MSW's Service Worker:
From what I understand, the worker goes idle, then the browser terminates it, and then your requests fail. Is that correct, @jkinger? |
A good thread on why Service Workers are killed after becoming idle: w3c/ServiceWorker#980 |
I wonder if instead of trying to keep the worker alive and playing a guess game with the browser and its internal policies, we could detect that the browser has unregistered the worker (I do believe the worker's state change event should be emitted in that case) and if that happens, try to register and activate the worker again? |
Yes, all that you explained above sounds accurate as this just started happening within 6 months or so and only happens on Chromium-based browsers. Firefox doesn't have this issue. Your last post about "..try to register and activate the worker again" is what I've been thinking about too. Could I re-instantiate the MSW service again somehow (like below) when the service worker is de-registered or starts throwing errors?
Or would there be more to it? Or maybe something like a |
I think it's not something you should be doing manually. I wonder if that unregistration that Chrome does trigger the state change event on the worker. @jkinger, can you please try this out in your scenario? navigator.serviceWorker.controller.addEventListener('statechange', (event) => {
console.log(event.target.state)
}) What does this print when Chrome terminates the idle worker? Does it print anything at all? I hope Chrome doesn't go around the worker's lifecycle and the termination that it initiates still causes the worker to go into something like "redundant". If we can detect that via a listener, we can call something akin to |
I've taken your recommendation and code to see if I can get notified when Chrome stops the service worker but unfortunately not getting any events for "'statechange'" when Chrome stops it. I know what you're getting at so trying to explore other listeners as well. FWIW another observation I've noticed is Chrome doesn't seem to unregister the Service Worker but only stops it. When I return to the Browser / Tab and start interacting with the page again Chrome starts the Server Worker again and it's still under the same Registration ID it was first registered with. Thanks for your help thus far. |
Yeah, this makes sense. Aligns with what Chrome is saying they do.
Does this "solve" the issue then? Can you describe to me the scenario when Chrome kills the worker and that causes issues? |
Yeah, you would think, right? But it doesn't, I've been monitoring the Service Worker via chrome://serviceworker-internals/?devtools and I see when Chrome stops it after the set time of inactivity and then I see it being started again when I start interacting with the page but nothing is being intercepted as before. There is a disconnect happening somewhere during the Stop / Restart of this Worker that's keeping MSW inoperable and that is what I'm trying to pin down. If Chrome re-starts it again then why doesn't MSW start responding to requests again? That's the part that doesn't make sense. It's like the Starting, Stopping then Starting again throws it off somehow. The only way I'm able to get MSW to start responding again is by doing a Refresh. |
I can imagine if terminating the worker also removes any listeners attached to it, MSW will lose any connection with the worker. We rely on a MessageChannel to talk to the worker. If that gets shutdown and doesn't revive, MSW won't work.
This is a strong indication that's precisely what's happening. |
I finally identified the root cause: when Chrome stops and then restarts the service worker, it creates a new instance of Fortunately, all the listeners remain connected and active, so I'm not yet sufficiently familiar with the MSW code to suggest a comprehensive solution, but I managed to devise a quick, albeit makeshift, fix. If implemented in the App before a fetch, it should temporarily resolve the issue. Here's what the fix looks like:
By calling I've updated my Github repo (as well as the live site) with this fix, so anyone interested can see it in action. It’s not the most elegant solution, but it should suffice until a more definitive fix is developed. |
@kettanaito , any updates on this? Can we prioritize this issue? |
@jkinger, thanks for sharing the findings! So Chrome does re-registers the worker but we are loosing the values stores on its global scope. Interesting. Due to how isolated workers are by design, I doubt there's plenty of ways for us to persist those values (active client ids). I wonder if there's a way to catch that re-registration on the
worker.addEventListener('statechange', () => {
console.log('is this called?')
}) If we found a way for us to react to this behavior, we could re-establish the activation with the worker, which would add the current client into the active clients on the worker's side. @pahieiev, I'm not looking into this issue right now. You (your company) can prioritize this issue by becoming our Golden sponsor. I would be happy to look into this in more detail then. You are also fee to take the initiative and debug this deeper. |
Prerequisites
Environment check
msw
versionBrowsers
Chromium (Chrome, Brave, etc.)
Reproduction repository
https://github.com/jkinger/msw-react
Reproduction steps
You can either clone the provided repo or use the Github Pages link here: https://jkinger.github.io/msw-react/
If Cloning the Repo
App Url
Note: I had a similar issue open in v1 and closed in hopes this would be addressed in v2.
Current behavior
If the Chrome tab is left open (no DevTools) with no user activity for at least 5 minutes and you come back after that time you'll notice MSW stops intercepting requests.
Expected behavior
If the Chrome tab is left open with no user activity for at least 5 minutes and you come back after that time MSW should still be intercepting requests as before.
The text was updated successfully, but these errors were encountered: