EventBuzz_Backend/src/config/redisConnection.js

94 lines
2.5 KiB
JavaScript

/**
* BullMQ / ioredis connection for concierge queues.
* DigitalOcean Managed Redis (port 25061) requires TLS — use rediss:// or REDIS_TLS=true.
*/
function parseRedisUrl(raw) {
const url = String(raw || 'redis://127.0.0.1:6379').trim();
try {
return new URL(url);
} catch {
return null;
}
}
function shouldUseTls(parsed) {
if (!parsed) return false;
const force =
String(process.env.REDIS_TLS || '').trim().toLowerCase() === '1' ||
String(process.env.REDIS_TLS || '').trim().toLowerCase() === 'true';
if (force) return true;
if (parsed.protocol === 'rediss:') return true;
if (parsed.port === '25061') return true;
if (parsed.hostname && parsed.hostname.includes('ondigitalocean.com')) return true;
return false;
}
/**
* Options for BullMQ `connection` (ioredis). maxRetriesPerRequest must be null for workers.
* @returns {import('ioredis').RedisOptions}
*/
function getBullMQConnection() {
const raw = process.env.REDIS_URL || 'redis://127.0.0.1:6379';
const parsed = parseRedisUrl(raw);
const conn = {
maxRetriesPerRequest: null,
enableReadyCheck: true,
retryStrategy(times) {
return Math.min(times * 300, 8000);
},
};
if (!parsed) {
return { ...conn, host: '127.0.0.1', port: 6379 };
}
Object.assign(conn, {
host: parsed.hostname,
port: Number(parsed.port) || 6379,
username: parsed.username || undefined,
password: parsed.password ? decodeURIComponent(parsed.password) : undefined,
});
if (parsed.pathname && parsed.pathname.length > 1) {
const db = Number(parsed.pathname.slice(1));
if (!Number.isNaN(db)) conn.db = db;
}
if (shouldUseTls(parsed)) {
conn.tls = {};
if (!parsed.port) conn.port = 25061;
}
return conn;
}
/**
* Verify Redis is reachable at startup (workers).
*/
async function verifyRedisConnection() {
const Redis = require('ioredis');
const opts = getBullMQConnection();
const client = new Redis(opts);
try {
await client.ping();
const tlsNote = opts.tls ? ' (TLS)' : '';
console.log(`[redis] connected: ${opts.host}:${opts.port}${tlsNote}`);
} catch (err) {
const hint = opts.tls
? ''
: '\n Hint: DigitalOcean Managed Redis needs TLS. Set REDIS_TLS=true or use rediss:// in REDIS_URL.';
throw new Error(`Redis connection failed: ${err.message}${hint}`);
} finally {
client.disconnect();
}
}
module.exports = {
getBullMQConnection,
verifyRedisConnection,
shouldUseTls,
parseRedisUrl,
};