Skip to content

Commit

Permalink
619: Ensure that background refresh only calls fn once.
Browse files Browse the repository at this point in the history
  • Loading branch information
Richard Allwood committed Nov 23, 2023
1 parent 5cc5f26 commit 0dee93e
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 1 deletion.
4 changes: 3 additions & 1 deletion src/caching.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,9 @@ export async function caching<S extends Store, T extends object = never>(
const cacheTTL = typeof ttl === 'function' ? ttl(value) : ttl;
const remainingTtl = await store.ttl(key);
if (remainingTtl !== -1 && remainingTtl < args.refreshThreshold) {
fn().then((result) => store.set<T>(key, result, cacheTTL));
coalesceAsync(`+++${key}`, fn).then((result) =>
store.set<T>(key, result, cacheTTL),
);
}
}
return value;
Expand Down
36 changes: 36 additions & 0 deletions test/caching.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -388,4 +388,40 @@ describe('caching', () => {
).resolves.toEqual(1);
});
});

it('only calls fn once when refreshing the cache', async () => {
const key = faker.string.alpha(20);
let callCount = 0;
cache = await caching('memory', {
ttl: 5 * 1000,
refreshThreshold: 4 * 1000,
});
const resolveAfter =
(timeout: number, value: number) => (): Promise<number> =>
new Promise((resolve) =>
setTimeout(() => {
callCount++;
resolve(value);
}, timeout),
);
const delay = (timeout: number) =>
new Promise((resolve) => setTimeout(resolve, timeout));

let value = await cache.wrap(key, resolveAfter(100, 1));
expect(value).toEqual(1);
expect(callCount).toEqual(1);

await delay(1100);
for (let i = 0; i < 6; i++) {
// Only the first fn should be called - returning 2
value = await cache.wrap(key, resolveAfter(2000, 2 + i));
expect(value).toEqual(1);
expect(callCount).toEqual(1);
}

await delay(2100);
value = await cache.wrap(key, resolveAfter(2000, 8));
expect(value).toEqual(2);
expect(callCount).toEqual(2);
});
});

0 comments on commit 0dee93e

Please sign in to comment.