Files
scoreodonto.com/backend/dist/infra/cache/dragonfly.js
T

118 lines
3.8 KiB
JavaScript

"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.dragonfly = void 0;
const ioredis_1 = __importDefault(require("ioredis"));
const env_1 = require("../../config/env");
const logger_1 = require("../../config/logger");
class DragonflyClient {
client;
ttl;
constructor() {
this.ttl = parseInt(env_1.env.DRAGONFLY_TTL_SECONDS, 10);
this.client = new ioredis_1.default(env_1.env.DRAGONFLY_URL, {
// null = não limita tentativas por comando; a reconexão é gerenciada pelo retryStrategy
maxRetriesPerRequest: null,
enableReadyCheck: false,
lazyConnect: true,
// Falha imediata quando desconectado — evita fila infinita em memória
enableOfflineQueue: false,
// Reconexão exponencial: 200ms → 400ms → ... → 30s
retryStrategy(times) {
const delay = Math.min(200 * 2 ** times, 30_000);
return delay;
},
});
this.client.on('connect', () => logger_1.logger.info('DragonflyDB conectado'));
this.client.on('ready', () => logger_1.logger.info('DragonflyDB pronto'));
this.client.on('error', (err) => logger_1.logger.error({ msg: 'DragonflyDB erro', code: err.code }));
this.client.on('close', () => logger_1.logger.warn('DragonflyDB conexão fechada — reconectando...'));
}
/** true se o cliente está conectado e pronto */
isAlive() {
return this.client.status === 'ready';
}
async connect() {
// Inicia conexão em background — não bloqueia o startup se Redis estiver fora
// retryStrategy cuida da reconexão automática
this.client.connect().catch(() => { });
}
async get(key) {
try {
return await this.client.get(key);
}
catch {
return null;
}
}
async getJson(key) {
try {
const raw = await this.client.get(key);
if (!raw)
return null;
return JSON.parse(raw);
}
catch {
return null;
}
}
async set(key, value, ttlSeconds) {
try {
const ttl = ttlSeconds ?? this.ttl;
if (ttl > 0) {
await this.client.set(key, value, 'EX', ttl);
}
else {
await this.client.set(key, value);
}
}
catch { /* Redis indisponível — ignora silenciosamente */ }
}
async setJson(key, value, ttlSeconds) {
try {
const ttl = ttlSeconds ?? this.ttl;
if (ttl > 0) {
await this.client.set(key, JSON.stringify(value), 'EX', ttl);
}
else {
await this.client.set(key, JSON.stringify(value));
}
}
catch { /* Redis indisponível — ignora silenciosamente */ }
}
async psetex(key, ttlMs, value) {
try {
await this.client.psetex(key, ttlMs, value);
}
catch { }
}
async del(key) {
try {
await this.client.del(key);
}
catch { }
}
async exists(key) {
try {
const count = await this.client.exists(key);
return count > 0;
}
catch {
return false;
}
}
/** Publica em um canal pub/sub (usado para broadcasting de QR/status) */
async publish(channel, message) {
try {
await this.client.publish(channel, message);
}
catch { }
}
raw() {
return this.client;
}
}
exports.dragonfly = new DragonflyClient();