import { createClient, type RedisClientType } from "npm:redis@4"; import { config } from "./config.ts"; /** * Dos clientes Redis separados, autenticados con usuarios ACL distintos * (panels_iam_redis ~iam:*, panels_core_redis ~core:*, ver * db/provision/05-redis-acl.sh). El prefijo de llave (`iam:`/`core:`) * refuerza pero NO sustituye el ACL del servidor -- la separación real la * da la credencial, no la convención de nombres. * * Redis no es fuente de verdad de nada aquí: sesiones (iam:session:*) se * recuperan con un re-login; cache (core:cache:*) se recalcula desde * Postgres. Por eso no hay lógica de reintento agresivo ni persistencia * más allá de lo que ya ofrece el servidor. */ let iamClient: RedisClientType | null = null; let coreClient: RedisClientType | null = null; export async function getIamRedis(): Promise { if (!iamClient) { iamClient = createClient({ url: config.redisUrlIam }) as RedisClientType; iamClient.on("error", (err) => console.error("[redis:iam]", err)); await iamClient.connect(); } return iamClient; } export async function getCoreRedis(): Promise { if (!coreClient) { coreClient = createClient({ url: config.redisUrlCore }) as RedisClientType; coreClient.on("error", (err) => console.error("[redis:core]", err)); await coreClient.connect(); } return coreClient; } export async function pingRedis(): Promise<{ iam: boolean; core: boolean }> { const [iam, core] = await Promise.all([ getIamRedis().then((c) => c.ping()).then(() => true).catch(() => false), getCoreRedis().then((c) => c.ping()).then(() => true).catch(() => false), ]); return { iam, core }; } export async function closeRedis(): Promise { await iamClient?.quit().catch(() => {}); await coreClient?.quit().catch(() => {}); iamClient = null; coreClient = null; }