From 999e828e5cf8e8a935de14cd14b8cbb2da50b2b1 Mon Sep 17 00:00:00 2001 From: Laurent Chenay Date: Fri, 29 Dec 2023 08:43:47 +0100 Subject: [PATCH] Add refreshThreshold as parameter of wrap function. Fix #606 --- README.md | 2 +- src/caching.ts | 9 +++++---- src/multi-caching.ts | 3 ++- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index d4b569f2..efde2c8d 100644 --- a/README.md +++ b/README.md @@ -158,7 +158,7 @@ See unit tests in [`test/multi-caching.test.ts`](./test/multi-caching.test.ts) f ### Refresh cache keys in background Both the `caching` and `multicaching` modules support a mechanism to refresh expiring cache keys in background when using the `wrap` function. -This is done by adding a `refreshThreshold` attribute while creating the caching store. +This is done by adding a `refreshThreshold` attribute while creating the caching store or passing it to the `wrap` function. If `refreshThreshold` is set and after retrieving a value from cache the TTL will be checked. If the remaining TTL is less than `refreshThreshold`, the system will update the value asynchronously, diff --git a/src/caching.ts b/src/caching.ts index 5efa9863..7bdd5366 100644 --- a/src/caching.ts +++ b/src/caching.ts @@ -43,7 +43,7 @@ export type Cache = { get: (key: string) => Promise; del: (key: string) => Promise; reset: () => Promise; - wrap(key: string, fn: () => Promise, ttl?: WrapTTL): Promise; + wrap(key: string, fn: () => Promise, ttl?: WrapTTL, refreshThreshold?: Milliseconds): Promise; store: S; }; @@ -101,7 +101,8 @@ export function createCache( * const result = await cache.wrap('key', () => Promise.resolve(1)); * */ - wrap: async (key: string, fn: () => Promise, ttl?: WrapTTL) => { + wrap: async (key: string, fn: () => Promise, ttl?: WrapTTL, refreshThreshold?: Milliseconds) => { + const refreshThresholdConfig = refreshThreshold || args?.refreshThreshold || 0; return coalesceAsync(key, async () => { const value = await store.get(key); if (value === undefined) { @@ -109,10 +110,10 @@ export function createCache( const cacheTTL = typeof ttl === 'function' ? ttl(result) : ttl; await store.set(key, result, cacheTTL); return result; - } else if (args?.refreshThreshold) { + } else if (refreshThresholdConfig) { const cacheTTL = typeof ttl === 'function' ? ttl(value) : ttl; const remainingTtl = await store.ttl(key); - if (remainingTtl !== -1 && remainingTtl < args.refreshThreshold) { + if (remainingTtl !== -1 && remainingTtl < refreshThresholdConfig) { coalesceAsync(`+++${key}`, fn).then((result) => store.set(key, result, cacheTTL), ); diff --git a/src/multi-caching.ts b/src/multi-caching.ts index 0667e232..f0b5069b 100644 --- a/src/multi-caching.ts +++ b/src/multi-caching.ts @@ -35,6 +35,7 @@ export function multiCaching( key: string, fn: () => Promise, ttl?: WrapTTL, + refreshThreshold?: Milliseconds ): Promise { let value: T | undefined; let i = 0; @@ -54,7 +55,7 @@ export function multiCaching( Promise.all( caches.slice(0, i).map((cache) => cache.set(key, value, cacheTTL)), ).then(); - caches[i].wrap(key, fn, ttl).then(); // call wrap for store for internal refreshThreshold logic, see: src/caching.ts caching.wrap + caches[i].wrap(key, fn, ttl, refreshThreshold).then(); // call wrap for store for internal refreshThreshold logic, see: src/caching.ts caching.wrap } return value; },