summaryrefslogtreecommitdiff
path: root/addons
diff options
context:
space:
mode:
authorPierre Paridans <app@odoo.com>2020-09-24 12:51:45 +0000
committerPierre Paridans <app@odoo.com>2020-10-02 12:21:29 +0000
commitef2d323c3a029cb58ee219f06a9809aa52d108b3 (patch)
tree5735189c12c431e4a6bb2398e1d4cd636bf192e7 /addons
parent20eddda77d0ed6f2bb9b61d8ae4194e960ccc4ff (diff)
[FIX] website_event_track: don't clutter the ServiceWorker cache
This commit aims at reducing the requests stored in the cache by filtering out the error-like requests (404, 500...) and the "opaque" requests. Also this commit adds a check for the cache size to prevent it from filling up, resulting into a locked out cache (blocking certain requests). Co-authored-by: Olivier Dony <odo@odoo.com>
Diffstat (limited to 'addons')
-rw-r--r--addons/website_event_track/static/src/js/service_worker.js34
1 files changed, 34 insertions, 0 deletions
diff --git a/addons/website_event_track/static/src/js/service_worker.js b/addons/website_event_track/static/src/js/service_worker.js
index aec317435ef..4b8772de3c3 100644
--- a/addons/website_event_track/static/src/js/service_worker.js
+++ b/addons/website_event_track/static/src/js/service_worker.js
@@ -3,6 +3,8 @@ importScripts("/website_event_track/static/lib/idb-keyval/idb-keyval.js");
const PREFIX = "odoo-event";
const SYNCABLE_ROUTES = ["/event/track/toggle_reminder"];
const CACHABLE_ROUTES = ["/web/webclient/version_info"];
+const MAX_CACHE_SIZE = 512 * 1024 * 1024; // 500 MB
+const MAX_CACHE_QUOTA = 0.5;
const { Store, set, get, del } = idbKeyval;
const pendingRequestsQueueName = `${PREFIX}-pending-requests`;
@@ -46,6 +48,18 @@ const isCachableURL = canHandleRoutes(CACHABLE_ROUTES);
/**
*
+ * @returns {boolean} true if navigator has a quota we can read and we reached it
+ */
+const isCacheFull = async () => {
+ if (!("storage" in navigator && "estimate" in navigator.storage)) {
+ return false;
+ }
+ const { usage, quota } = await navigator.storage.estimate();
+ return usage / quota > MAX_CACHE_QUOTA || usage > MAX_CACHE_SIZE;
+};
+
+/**
+ *
* @return {Promise}
*/
const fetchToCacheOfflinePage = () => caches.open(cacheName).then((cache) => cache.add(offlineRoute));
@@ -133,6 +147,26 @@ const buildEmptyResponse = () => new Response(JSON.stringify({ jsonrpc: "2.0", i
* @returns {Promise}
*/
const cacheRequest = async (request, response) => {
+ // don't even attempt to cache:
+ // - error pages (why cache that?)
+ // - non-"basic" response types, which include tracker 1-time opaque requests
+ // that are consuming cache space for no reason (namely due to padding MBs accounted for
+ // each opaque request)
+ if (!response || !response.ok || response.type !== "basic") {
+ console.error(`ignoring cache for ${request.url} => ${response.type}, mode: ${request.mode}, cache: ${request.cache}`);
+ return;
+ }
+
+ // never blow up cache quota, as it will break things, and the space
+ // is shared with cookies and localStorage
+ if (await isCacheFull()) {
+ // TODO: clear some part of the cache to free older/less-relevant content
+ console.log("Cache full, not caching!");
+ return;
+ }
+
+ console.log(`grant cache for ${request.url} => ${response.type}, mode: ${request.mode}, cache: ${request.cache},
+ isGet: ${isGET(request)}, isCachable: ${isCachableURL(request.url)}`);
if (isGET(request)) {
const cache = await caches.open(cacheName);
await cache.put(request, response.clone());