Some checks failed
Build & Deploy KLZ Cables / build-and-deploy (push) Failing after 4m27s
55 lines
1.6 KiB
TypeScript
55 lines
1.6 KiB
TypeScript
import { createClient, type RedisClientType } from 'redis';
|
|
import type { CacheService, CacheSetOptions } from './cache-service';
|
|
|
|
export type RedisCacheServiceOptions = {
|
|
url: string;
|
|
keyPrefix?: string;
|
|
};
|
|
|
|
// Thin wrapper around shared Redis (platform provides host `redis`).
|
|
// Values are JSON-serialized.
|
|
export class RedisCacheService implements CacheService {
|
|
private readonly client: RedisClientType;
|
|
private readonly keyPrefix: string;
|
|
|
|
constructor(options: RedisCacheServiceOptions) {
|
|
this.client = createClient({ url: options.url });
|
|
this.keyPrefix = options.keyPrefix ?? '';
|
|
|
|
// Fire-and-forget connect.
|
|
this.client.connect().catch((err) => {
|
|
// We can't use getServerAppServices() here because it might cause a circular dependency
|
|
// during initialization. But we can log to console as a fallback or use a global logger if we had one.
|
|
// For now, let's just use console.error as this is a low-level service.
|
|
console.error('Redis connection error:', err);
|
|
});
|
|
}
|
|
|
|
private k(key: string) {
|
|
return `${this.keyPrefix}${key}`;
|
|
}
|
|
|
|
async get<T>(key: string): Promise<T | undefined> {
|
|
const raw = await this.client.get(this.k(key));
|
|
if (raw == null) return undefined;
|
|
return JSON.parse(raw) as T;
|
|
}
|
|
|
|
async set<T>(key: string, value: T, options?: CacheSetOptions): Promise<void> {
|
|
const ttl = options?.ttlSeconds;
|
|
const raw = JSON.stringify(value);
|
|
|
|
if (ttl && ttl > 0) {
|
|
await this.client.set(this.k(key), raw, { EX: ttl });
|
|
return;
|
|
}
|
|
|
|
await this.client.set(this.k(key), raw);
|
|
}
|
|
|
|
async del(key: string): Promise<void> {
|
|
await this.client.del(this.k(key));
|
|
}
|
|
}
|
|
|