Skip to content

Commit

Permalink
RD-235 Implement Cache API max size and purging + cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
petrsloup committed Mar 22, 2024
1 parent 1f2ca3b commit 2bc026e
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 9 deletions.
35 changes: 27 additions & 8 deletions src/caching.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ const LOCAL_CACHE_PROTOCOL_SOURCE = "localcache_source";
const LOCAL_CACHE_PROTOCOL_DATA = "localcache";
const LOCAL_CACHE_NAME = "maptiler_sdk";

const CACHE_LIMIT_ITEMS = 1000;
const CACHE_LIMIT_CHECK_INTERVAL = 100;

export function localCacheTransformRequest(
reqUrl: URL,
resourceType?: ResourceType,
Expand All @@ -32,10 +35,26 @@ export function localCacheTransformRequest(
return reqUrl.href;
}

let cacheInstance: Cache;

async function getCache() {
if (!cacheInstance) {
cacheInstance = await caches.open(LOCAL_CACHE_NAME);
}
return cacheInstance;
}

let cachePutCounter = 0;
async function limitCache() {
const cache = await getCache();
const keys = await cache.keys();
const toPurge = keys.slice(0, Math.max(keys.length - CACHE_LIMIT_ITEMS, 0));
for (const key of toPurge) {
cache.delete(key);
}
}

export function registerLocalCacheProtocol() {
// TODO cleanup
// TODO make safer
// TODO cache cleaning ?
addProtocol(
LOCAL_CACHE_PROTOCOL_SOURCE,
async (
Expand Down Expand Up @@ -102,16 +121,12 @@ export function registerLocalCacheProtocol() {
};
};

// TODO do only once somehow
const cache = await caches.open(LOCAL_CACHE_NAME);

const cache = await getCache();
const cacheMatch = await cache.match(cacheKey);

if (cacheMatch) {
console.log("Cache hit", cacheKey);
return respond(cacheMatch);
} else {
console.log("Cache miss", cacheKey);
const requestInit: RequestInit = params;
requestInit.signal = abortController.signal;
const response = await fetch(fetchUrl, requestInit);
Expand All @@ -120,6 +135,10 @@ export function registerLocalCacheProtocol() {
// "DOMException: Cache.put() was aborted"
// can happen here because the response is not done streaming yet
});
if (++cachePutCounter > CACHE_LIMIT_CHECK_INTERVAL) {
limitCache();
cachePutCounter = 0;
}
}
return respond(response);
}
Expand Down
4 changes: 3 additions & 1 deletion src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,9 @@ class SdkConfig extends EventEmitter {
session = true;

/**
* TODO description
* Enables client-side caching of requests for tiles and fonts.
* The cached requests persist multiple browser sessions and will be reused when possible.
* Works only for requests to the MapTiler Cloud API when sessions are enabled.
*/
caching = true;

Expand Down

0 comments on commit 2bc026e

Please sign in to comment.