Handle unreliable in-memory storage for Manifest v3
Background / User story
Manifest v3 forces us to run our background scripts in a service worker, which can be suspended/terminated at any time. Therefore we need to make sure that we can handle unreliable in-memory storage to avoid regressions.
Potential breakage:
- Incorrect allowlisting state shown in icon
- Blocked counter shown/hidden in icon when it shouldn't be.
- Incorrect blocked counter shown in icon.
- Developer tools panel content not reset on page load (incl. on reload).
- Notification no longer shown (i.e. is dismissed).
- Nothing happens when interacting with desktop notification.
- Language filter list recommendation notification not shown.
- Changes to preferences for total blocked counter aren't saved.
- Error message not shown in settings page when downloadable filter lists contains disabled filters.
- Unable to determine meta data about current session (i.e. is first-run, encountered data corruption, settings were reinitialized).
- Block element context menu item and icon popup button shown as expected (e.g. not shown for allowlisted pages; not shown for non-HTML pages).
- Extension tries to recover from data corruption (e.g. reset filter settings; show "problem" notification) each time the service worker wakes up, instead of only each time the extension is loaded.
- Incorrect "corrupted" query string parameter value is passed to uninstall page.
What to change
- Design: N/A
- Research: N/A
- Spec: N/A
- Legal: N/A
-
Development:
- Deterministic states: Reevaluate the values of the following variables whenever the service worker activates:
-
lib/icon:(values already being restored when service worker wakes up)allowlistedState
-
lib/stats:(values already being restored when service worker wakes up)activeTabIds
activeTabIdByWindowId
-
- Non-deterministic states: Store and retrieve the values of the following variables using
browser.storage.session
when in a service worker:- lib/browserAction:
badgeStateByPage
- lib/devtools:
-
(see #1086 (closed))panels
reloadStateByPage
-
- lib/filterComposer:
readyActivePages
-
lib/filterConfiguration:(values already being restored when service worker wakes up)disabledFilterCounters
- lib/icon:
allowlistedState
- lib/notificationHelper:
activeNotification
buttonsByNotificationId
-
lib/prefs:(values already being restored when service worker wakes up; only a problem on Firefox <66 due to write-throttling of "blocked_total")overrides
- lib/recommendLanguage:
lastVisits
- lib/stats:
blockedPerPage
- lib/subscriptionInit:
-
(values already being restored when service worker wakes up; value may change when service worker wakes up)dataCorrupted
-
(value offirstRun
FirstRunInfo.foundSubscriptions
may change after recovery from data corruption; only used during first initialization) -
(value ofreinitialized
FirstRunInfo.foundStorage
may change after recovery from data corruption; only used during first initialization) -
(values already being restored when service worker wakes up)userNotificationCallback
-
- lib/browserAction:
- Deterministic states: Reevaluate the values of the following variables whenever the service worker activates:
Hints for testers
See list of potential breakage under "Background".
The above data used to be stored in memory, but now has to make use of browser.storage.session
, which currently has a 1MB quota. Therefore we should verify that we don't hit this quota (even with lots of tabs open) or that the extension at least degrades gracefully.
Hints for translators
N/A
Further information
Initialization code runs again on service worker activation in the following scenarios:
// yes
{
// yes
}
(() =>
{
// yes
})();
(async () =>
{
// yes
await syncFunc(); // function is executed synchronously (even as an `async` function)
// yes
await asyncFunc(); // function is executed asynchronously
// no
})();
setTimeout(() =>
{
// no
}, 0);
function foo()
{
// yes
}
foo();
new Promise((resolve) =>
{
// yes
resolve();
})
.then(() =>
{
// yes
});
Therefore any data that is added to memory in the places marked with "no" is not persisted across service worker activations.