Skip to content

Commit

Permalink
Add refreshThreshold as parameter of wrap function. Fix jaredwray#606
Browse files Browse the repository at this point in the history
  • Loading branch information
lchenay committed Dec 29, 2023
1 parent 8475076 commit 999e828
Show file tree
Hide file tree
Showing 3 changed files with 8 additions and 6 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
9 changes: 5 additions & 4 deletions src/caching.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ export type Cache<S extends Store = Store> = {
get: <T>(key: string) => Promise<T | undefined>;
del: (key: string) => Promise<void>;
reset: () => Promise<void>;
wrap<T>(key: string, fn: () => Promise<T>, ttl?: WrapTTL<T>): Promise<T>;
wrap<T>(key: string, fn: () => Promise<T>, ttl?: WrapTTL<T>, refreshThreshold?: Milliseconds): Promise<T>;
store: S;
};

Expand Down Expand Up @@ -101,18 +101,19 @@ export function createCache<S extends Store, C extends Config>(
* const result = await cache.wrap('key', () => Promise.resolve(1));
*
*/
wrap: async <T>(key: string, fn: () => Promise<T>, ttl?: WrapTTL<T>) => {
wrap: async <T>(key: string, fn: () => Promise<T>, ttl?: WrapTTL<T>, refreshThreshold?: Milliseconds) => {
const refreshThresholdConfig = refreshThreshold || args?.refreshThreshold || 0;
return coalesceAsync(key, async () => {
const value = await store.get<T>(key);
if (value === undefined) {
const result = await fn();
const cacheTTL = typeof ttl === 'function' ? ttl(result) : ttl;
await store.set<T>(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<T>(key, result, cacheTTL),
);
Expand Down
3 changes: 2 additions & 1 deletion src/multi-caching.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ export function multiCaching<Caches extends Cache[]>(
key: string,
fn: () => Promise<T>,
ttl?: WrapTTL<T>,
refreshThreshold?: Milliseconds
): Promise<T> {
let value: T | undefined;
let i = 0;
Expand All @@ -54,7 +55,7 @@ export function multiCaching<Caches extends Cache[]>(
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;
},
Expand Down

0 comments on commit 999e828

Please sign in to comment.