Skip to content

Instantly share code, notes, and snippets.

@Fredkiss3
Last active January 3, 2023 14:51
Show Gist options
  • Save Fredkiss3/3c24411676de314dc65bd0a0995eaaeb to your computer and use it in GitHub Desktop.
Save Fredkiss3/3c24411676de314dc65bd0a0995eaaeb to your computer and use it in GitHub Desktop.
Redis Cache Lib
import * as Redis from 'redis';
import * as superjson from 'superjson';
export class Cache {
private static client: Redis.RedisClient;
private static readonly prefix = process.env.CACHE_PREFIX || '';
private static readonly bypassCache = process.env.CACHE_BYPASS === 'true';
static async get<T>(key: (string | number | Date)[], getValue: () => Promise<T>): Promise<T> {
if (this.bypassCache) {
return getValue();
}
if (!this.client || !this.client.isReady) {
await this.initializeClient();
}
const cacheKey = this.buildCacheKey(key);
const value = await this.client.get(cacheKey);
if (value) {
return superjson.parse<T>(value);
} else {
const newValue = await getValue();
await this.update(key, newValue);
return newValue;
}
}
static async update(key: (string | number | Date)[], value: any) {
if (this.bypassCache) {
return;
}
if (!this.client || !this.client.isReady) {
await this.initializeClient();
}
const cacheKey = this.buildCacheKey(key);
const serializedValue = superjson.stringify(value);
await this.client.set(cacheKey, serializedValue);
await this.client.expire(cacheKey, Number(process.env.CACHE_TTL));
}
static async invalidate(key: (string | number | Date)[]) {
if (this.bypassCache) {
return;
}
if (!this.client || !this.client.isReady) {
await this.initializeClient();
}
const cacheKey = this.buildCacheKey(key);
const keys = await this.client.keys(`${cacheKey}*`);
if (keys.length > 0) {
await this.client.del(keys);
}
}
static async clear() {
if (this.bypassCache) {
return;
}
if (!this.client || !this.client.isReady) {
await this.initializeClient();
}
await this.invalidate([]);
}
private static async initializeClient() {
this.client = await Redis.createClient({ url: process.env.REDIS_URL });
await this.client.connect();
}
static async dispose(){
await this.client?.disconnect();
}
private static buildCacheKey(key: (string | number | Date)[]) {
return [this.prefix, ...key].map(element => {
if (element instanceof Date) {
return element.getTime();
}
return element;
}).join('_');
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment