Created
July 14, 2022 17:38
-
-
Save ctrlShiftBryan/25587418831f0a9d50d1c5dda3f67ed9 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { createClient, RedisClientType, RedisModules, RedisScripts } from '@node-redis/client'; | |
import { getFromCache } from './cache.server'; | |
describe('Name of the group', () => { | |
let client : RedisClientType<RedisModules, RedisScripts>; | |
beforeAll(async () => { | |
client = createClient({ url: process.env.REDIS_URL }); | |
await client.connect(); | |
}); | |
beforeEach(async () => { | |
await client.flushAll(); | |
}); | |
it('it should return result of promise', async () => { | |
const res = await getFromCache({ promise: async () => ({ call: 1 }), term: 'test', maxAge: 1, client }); | |
expect(res).toEqual({ call: 1 }); | |
}); | |
it('it should return cached if not stale', async () => { | |
const res = await getFromCache({ promise: async () => ({ call: 1 }), term: 'test', maxAge: 1, client }); | |
expect(res).toEqual({ call: 1 }); | |
// it should return call from first time | |
const futureDate = new Date().getTime() + 100_000; | |
const res2 = await getFromCache({ promise: async () => ({ call: 2 }), term: 'test', maxAge: 1, client, now: futureDate }); | |
expect(res2).toEqual({ call: 1 }); | |
expect(res).toStrictEqual(res2); | |
}); | |
it('it should only return stale once', async () => { | |
// first call not cached | |
const res = await getFromCache({ promise: async () => ({ call: 1 }), term: 'test', maxAge: 1, client }); | |
expect(res).toEqual({ call: 1 }); | |
// it should return stale the first time it's called and is stale | |
const futureDate = new Date().getTime() + 100_000; | |
const res2 = await getFromCache({ promise: async () => ({ call: 2 }), term: 'test', maxAge: 1, client, now: futureDate }); | |
expect(res2).toEqual({ call: 1 }); | |
expect(res).toStrictEqual(res2); | |
const futureDate2 = new Date().getTime() + 200_000; | |
// it should return previous call value since it was stale but should have re-cached | |
const res3 = await getFromCache({ promise: async () => ({ call: 3 }), term: 'test', maxAge: 1, client, now: futureDate2 }); | |
expect(res3).toEqual({ call: 2 }); | |
}); | |
afterAll(async () => { | |
await client.quit(); | |
}); | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* eslint-disable no-console */ | |
import { createClient, RedisClientType, RedisModules, RedisScripts } from '@node-redis/client'; | |
export async function clearFromCache(term: string): Promise<any> { | |
const client = createClient({ url: process.env.REDIS_URL }); | |
await client.connect(); | |
const result = await client.del(term); | |
return result; | |
} | |
export type getFromCacheParams = { | |
promise: () => Promise<any>, | |
term: string, | |
maxAge: number, | |
now?: number, | |
client: RedisClientType<RedisModules, RedisScripts>, | |
} | |
export async function getFromCache(params: getFromCacheParams): Promise<any> { | |
const { promise, term, maxAge, client } = params; | |
const result = await client.get(term); | |
const now = params.now || new Date().getTime(); | |
// if its in redis | |
if (result) { | |
// before returning check if its expired | |
const data = JSON.parse(result); | |
const miliseconds = now - data.time; | |
const age = Math.round(miliseconds / 60_000); | |
const expired = age >= maxAge; | |
const res = { ...data, age, expired }; | |
// reload but don't wait if expired | |
if (expired) { | |
console.log('Cache expired, reloading...'); | |
promise().then((data: any) => { client.set(term, JSON.stringify({ term: data, time: now })); }); | |
} | |
console.log('Cache hit!'); | |
// return the term | |
return res.term; | |
} | |
console.log('Cache miss!'); | |
// if its not in redi call the promise to get it and save to redis | |
const json = await promise(); | |
client.set(term, JSON.stringify({ term: json, time: now })); | |
return json; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment