Files
Epicnabbo-Catalogus-Updated…/src/lib/cached-db.ts
T
openhands 6a67fb6e83 refactor: remove additional dead exports and unused actions
Remove buildFontUrl, measureText, uncached, invalidateCache, fetchJsonWithFlareSolver, upsertPermission, deletePermission, bulkImportPermissions, clearAllPermissions, bulkDeletePermissions, bulkDeletePhotos, userReplyTicket, closeTicketByUser. Update staff-smoke-contract test for bulkDeletePhotos removal.
2026-08-07 19:19:05 +02:00

53 lines
1.1 KiB
TypeScript

import "server-only";
import { logger } from "@/lib/logger";
import { redis } from "@/lib/redis";
const DEFAULT_CACHE_TTL = 60;
function isRedisAvailable(): boolean {
return !!redis && redis.status !== "end";
}
export async function cachedQuery<T>(
cacheKey: string,
queryFn: () => Promise<T>,
ttl: number = DEFAULT_CACHE_TTL,
): Promise<T> {
if (!isRedisAvailable()) {
return queryFn();
}
try {
const cached = await redis?.get(cacheKey);
if (cached !== null && cached !== undefined) {
return JSON.parse(cached) as T;
}
} catch (err) {
logger.warn("[cache] read failed, falling back to DB", {
key: cacheKey,
error: String(err),
});
}
const result = await queryFn();
try {
await redis?.setex(cacheKey, ttl, JSON.stringify(result));
} catch (err) {
logger.warn("[cache] write failed, continuing without cache", {
key: cacheKey,
error: String(err),
});
}
return result;
}
/** Invalidate a single cache key immediately. */
export async function invalidateKey(key: string): Promise<number> {
if (!isRedisAvailable()) return 0;
if (!redis) return 0;
return redis.del(key);
}