Created
February 23, 2023 13:05
-
-
Save bruno-sartori/bd7f54aecdab7c8dcb7570442edc9207 to your computer and use it in GitHub Desktop.
RedisCache
This file contains hidden or 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 { RedisClient, createClient } from "redis"; | |
import { env } from "../env"; | |
/* | |
Usage: | |
// Define the cache | |
const cache = new RedisCache(60); | |
app.get("/products/recommended", async (req: Request, res: Response) => { | |
// Cache by userId as key | |
const products = await cache.get<Product[]>(req.userId, () => { | |
// Here's the function which refreshes the cache | |
return RecommendationModel.find(req.userId) | |
)}; | |
res.send(products); | |
}); | |
*/ | |
export class RedisCache { | |
private readonly cache: RedisClient; | |
private ttl: number; | |
constructor(ttl: number) { | |
// [1] define ttl and create redis connection | |
this.ttl = ttl; | |
this.cache = createClient({ | |
host: env.REDIS_HOST, | |
password: env.REDIS_PASSWORD, | |
}); | |
this.cache.on("connect", () => { | |
console.log(`Redis connection established`); | |
}); | |
this.cache.on("error", (error) => { | |
console.error(`Redis error, service degraded: ${error}`); | |
}); | |
} | |
// [2] generic function, takes `fetcher` argument which is meant to refresh the cache | |
async get<T>(key: string, fetcher: () => Promise<T>): Promise<T> { | |
// [3] if we're not connected to redis, bypass cache | |
if (!this.cache.connected) { | |
return await fetcher(); | |
} | |
return new Promise((resolve, reject) => { | |
this.cache.get(key, async (err, value) => { | |
if (err) return reject(err); | |
if (value) { | |
// [4] if value is found in cache, return it | |
return resolve(JSON.parse(value)); | |
} | |
// [5] if value is not in cache, fetch it and return it | |
const result = await fetcher(); | |
this.cache.set( | |
key, | |
JSON.stringify(result), | |
"EX", | |
this.ttl, | |
(err, reply) => { | |
if (err) return reject(err); | |
} | |
); | |
return resolve(result); | |
}); | |
}); | |
} | |
// [6] | |
del(key: string) { | |
this.cache.del(key); | |
} | |
flush() { | |
this.cache.flushall(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment