0

I'm working on an extension that should have a persistent service worker (while using Manifest V3).

I've tried the solution proposed in this answer (https://stackoverflow.com/a/66618269/10364842), and it works when tested by itself (I used the files from here to verify: https://bugs.chromium.org/p/chromium/issues/detail?id=1152255#c25).

However, when I put the code in the target extension, it doesn't prevent the worker from unloading.

I'm using worker_wrapper.js and injectScripts inside worker_wrapper.js. I added the code that keeps the service worker alive at the top of worker_wrapper.js (tried other locations as well).

I've verified that this code gets injected into one of the tabs:

chrome.runtime.connect({ name: 'keepAlive' });
          console.log('keepAlive');

I can see 'keepAlive' printed in the console for that tab.

However, the service worker still gets unloaded.

Last time I tested, it unloaded ~1 minute after the last 'keepAlive' was printed to the console.

So it seems it works sometimes, but often ~1 minute after keepAlive function is called the service worker still unloads.

Unfortunately I can't attach a minimal reproducible example, as I'm not sure what causes the problem. And the code from https://bugs.chromium.org/p/chromium/issues/detail?id=1152255#c25 works when run by itself.

I've also tested with DevTools open, and it still unloads (with the message 'DevTools was disconnected from the page. Once page is reloaded, DevTools will automatically reconnect.')

Tested Chrome versions: 99.0.4844.82, 101.0.4947.0
Tested OS: Ubuntu 20.04

Could there be any other bugs that could cause this? Should I try injecting the chrome.runtime.connect in each tab? Or try to run the keepAlive function every 55 seconds instead of every 4 minutes 55 seconds?

teg_brightly
  • 468
  • 6
  • 20
  • 1
    Without [MCVE](/help/mcve) the question isn't really answerable. I guess you may be using chrome.runtime.connect for messaging, in which case you don't need the code in that answer but you need to reconnect each of those ports before 5 minutes elapse. Similarly, for sendMessage with `return true` you need to call sendResponse within 5 minutes and keep that answer's code. Another possibility is that opening devtools for the service worker may reset the timer. – wOxxOm Mar 29 '22 at 19:22
  • @wOxxOm I've tried testing with all other `chrome.runtime.connect` disabled, but the worker still unloads. I'm wondering if not using `sendResponse` in `onMessage` could reset the timer and cause this (there seems to be a bug / change in MV3, where `sendMessage` expects `sendResponse` even if no callback was provided (unlike MV2) or `return true;` used, which results in "port closed before the response received" error). Also I've tested with devtools closed, but it also unloads. I'll try to create MCVE. – teg_brightly Mar 29 '22 at 21:00
  • 1
    Indeed, there is such a bug, so sendResponse must be always used. – wOxxOm Mar 29 '22 at 21:35
  • @wOxxOm confirming that the problem was related to this bug. It seems that either always using `sendResponse` or checking for `chrome.runtime.lastError` helps, however with multiple `onMessage` listeners (I guess that can't be avoided with multiple frames) there is still some uncertainty (for now still testing, but it might be related to one `onMessage` listener not existing yet on page load, and the other not expecting the request meant for the other `onMessage` listener and therefore not using `sendResponse`). Sidenote: `Receiving end does not exist` errors don't seem to affect the worker. – teg_brightly Apr 05 '22 at 12:08
  • That, or possibly when the page is being reloaded and `sendResponse` is not used in time (either it was async or some of the scripts with `onMessage` listeners have already unloaded). This is a guess, and I can't say for sure that this is what actually happens. It seems that checking everything for `lastError` generally helps though (not yet 100% sure). – teg_brightly Apr 05 '22 at 12:26
  • Update: checking everything for `chrome.runtime.lastError` doesn't seem to always help. The best way is to somehow ensure there are no `The message port closed before a response was received` errors. – teg_brightly Apr 07 '22 at 08:07

0 Answers0