stock-bot/libs/core/cache/src/connection-manager.ts
2025-06-26 16:12:27 -04:00

75 lines
1.9 KiB
TypeScript

import Redis from 'ioredis';
import { REDIS_DEFAULTS } from './constants';
import type { RedisConfig } from './types';
interface ConnectionConfig {
name: string;
singleton?: boolean;
db?: number;
redisConfig: RedisConfig;
logger?: unknown;
}
/**
* Simplified Redis Connection Manager
*/
export class RedisConnectionManager {
private static connections = new Map<string, Redis>();
private static instance: RedisConnectionManager;
static getInstance(): RedisConnectionManager {
if (!this.instance) {
this.instance = new RedisConnectionManager();
}
return this.instance;
}
/**
* Get or create a Redis connection
*/
getConnection(config: ConnectionConfig): Redis {
const { name, singleton = true, redisConfig } = config;
if (singleton) {
const existing = RedisConnectionManager.connections.get(name);
if (existing) {
return existing;
}
}
const connection = this.createConnection(redisConfig);
if (singleton) {
RedisConnectionManager.connections.set(name, connection);
}
return connection;
}
/**
* Create a new Redis connection
*/
private createConnection(config: RedisConfig): Redis {
return new Redis({
host: config.host,
port: config.port,
password: config.password,
username: config.username,
db: config.db ?? REDIS_DEFAULTS.DB,
maxRetriesPerRequest: config.maxRetriesPerRequest ?? REDIS_DEFAULTS.MAX_RETRIES,
connectTimeout: config.connectTimeout ?? REDIS_DEFAULTS.CONNECT_TIMEOUT,
commandTimeout: config.commandTimeout ?? REDIS_DEFAULTS.COMMAND_TIMEOUT,
lazyConnect: false,
...(config.tls && { tls: config.tls }),
});
}
/**
* Close all connections
*/
static async closeAll(): Promise<void> {
const promises = Array.from(this.connections.values()).map(conn => conn.quit().catch(() => {}));
await Promise.all(promises);
this.connections.clear();
}
}