import Redis from "ioredis"; import { Plugin } from "../plugin.class"; export class RedisPlugin extends Plugin { private static connectionPool: Map = new Map(); constructor( name: string, private redisClient: Redis, private prefix: string ) { super(name, [ "get", "set", "del", "exists", "lpop", "rpush", "llen", "lrange", "ltrim", "lpush", "rpop", ]); } private static isConnected(key: string): boolean { return ( RedisPlugin.connectionPool.has(key) && RedisPlugin.connectionPool.get(key).status === "ready" ); } static init( name: string, config: { host: string; port: number }, prefix: string ): RedisPlugin { const key = `${config.host}:${config.port}`; if (RedisPlugin.isConnected(key)) { return new RedisPlugin(name, RedisPlugin.connectionPool.get(key), prefix); } RedisPlugin.connectionPool.delete(key); const redisClient = new Redis({ host: config.host, port: config.port, commandTimeout: 10000, connectTimeout: 10000, lazyConnect: false, maxRetriesPerRequest: 1, enableReadyCheck: true, }); RedisPlugin.connectionPool.set(key, redisClient); return new RedisPlugin(name, redisClient, prefix); } async get(key: string): Promise { return JSON.parse(await this.redisClient.get(`${this.prefix}:${key}`)); } async set(key: string, value: any): Promise { await this.redisClient.set(`${this.prefix}:${key}`, JSON.stringify(value)); } async del(key: string): Promise { await this.redisClient.del(`${this.prefix}:${key}`); } async exists(key: string): Promise { const result = await this.redisClient.exists(`${this.prefix}:${key}`); return result === 1; } async lpop(key: string): Promise { return this.redisClient.lpop(`${this.prefix}:${key}`); } async rpush(key: string, value: any): Promise { return this.redisClient.rpush( `${this.prefix}:${key}`, JSON.stringify(value) ); } async llen(key: string): Promise { return this.redisClient.llen(`${this.prefix}:${key}`); } async lrange(key: string, start: number, stop: number): Promise { const results = await this.redisClient.lrange( `${this.prefix}:${key}`, start, stop ); return results.map((item) => JSON.parse(item)); } async ltrim(key: string, start: number, stop: number): Promise { await this.redisClient.ltrim(`${this.prefix}:${key}`, start, stop); } async lpush(key: string, value: any): Promise { return this.redisClient.lpush( `${this.prefix}:${key}`, JSON.stringify(value) ); } async rpop(key: string): Promise { return this.redisClient.rpop(`${this.prefix}:${key}`); } onFinish(): void { this.redisClient.quit(); } }