chinwagsocial/streaming/redis.js

65 lines
1.9 KiB
JavaScript

import { Redis } from 'ioredis';
import { parseIntFromEnvValue } from './utils.js';
/**
* @typedef RedisConfiguration
* @property {import('ioredis').RedisOptions} redisParams
* @property {string} redisPrefix
* @property {string|undefined} redisUrl
*/
/**
* @param {NodeJS.ProcessEnv} env the `process.env` value to read configuration from
* @returns {RedisConfiguration} configuration for the Redis connection
*/
export function configFromEnv(env) {
// ioredis *can* transparently add prefixes for us, but it doesn't *in some cases*,
// which means we can't use it. But this is something that should be looked into.
const redisPrefix = env.REDIS_NAMESPACE ? `${env.REDIS_NAMESPACE}:` : '';
let redisPort = parseIntFromEnvValue(env.REDIS_PORT, 6379, 'REDIS_PORT');
let redisDatabase = parseIntFromEnvValue(env.REDIS_DB, 0, 'REDIS_DB');
/** @type {import('ioredis').RedisOptions} */
const redisParams = {
host: env.REDIS_HOST || '127.0.0.1',
port: redisPort,
// Force support for both IPv6 and IPv4, by default ioredis sets this to 4,
// only allowing IPv4 connections:
// https://github.com/redis/ioredis/issues/1576
family: 0,
db: redisDatabase,
password: env.REDIS_PASSWORD || undefined,
};
// redisParams.path takes precedence over host and port.
if (env.REDIS_URL && env.REDIS_URL.startsWith('unix://')) {
redisParams.path = env.REDIS_URL.slice(7);
}
return {
redisParams,
redisPrefix,
redisUrl: typeof env.REDIS_URL === 'string' ? env.REDIS_URL : undefined,
};
}
/**
* @param {RedisConfiguration} config
* @param {import('pino').Logger} logger
* @returns {Redis}
*/
export function createClient({ redisParams, redisUrl }, logger) {
let client;
if (typeof redisUrl === 'string') {
client = new Redis(redisUrl, redisParams);
} else {
client = new Redis(redisParams);
}
client.on('error', (err) => logger.error({ err }, 'Redis Client Error!'));
return client;
}