aldikhan13

Custom Pub/Sub Redis For Caching Data

Oct 25th, 2021
774
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. import IORedis, { Redis } from 'ioredis'
  2. import { v4 as uuid } from 'uuid'
  3. import chalk from 'chalk'
  4. import { IPublisher } from '../interface/interface.publisher'
  5. import { ISubscriber } from '../interface/interface.subscriber'
  6.  
  7. /**
  8. * more example implementation check here my repository this link below
  9. * https://github.com/restuwahyu13/express-microservices-jobs-portal/tree/main/companies-service
  10. */
  11.  
  12. // publisher custom method
  13.  
  14. export class Publisher {
  15.     private static key: string
  16.     private static unique: string
  17.  
  18.     constructor(configs: Readonly<IPublisher>) {
  19.         Publisher.key = configs.key
  20.         Publisher.unique = uuid()
  21.         Publisher.set({ key: configs.key, unique: Publisher.unique })
  22.     }
  23.  
  24.     public static get(): Record<string, any> {
  25.         const options: Record<string, any> = {
  26.             key: Publisher.key,
  27.             unique: Publisher.unique
  28.         }
  29.         return options
  30.     }
  31.  
  32.     private static set(config: Record<string, any>): void {
  33.         Publisher.key = config.key
  34.         Publisher.unique = config.unique
  35.     }
  36.  
  37.     private redisConnect(): Redis {
  38.         const ioRedis = new IORedis({
  39.             host: process.env.REDIS_HOST,
  40.             port: +process.env.REDIS_PORT,
  41.             maxRetriesPerRequest: 50,
  42.             connectTimeout: 25000,
  43.             enableReadyCheck: true,
  44.             enableAutoPipelining: true
  45.         }) as IORedis.Redis
  46.  
  47.         return ioRedis
  48.     }
  49.  
  50.     public async setString(keyName: string, data: string, expiredAt: number): Promise<void> {
  51.         const ioRedis = this.redisConnect() as Redis
  52.         await ioRedis.set(`${keyName}:${Publisher.get().unique}`, data)
  53.         await ioRedis.expire(`${keyName}:${Publisher.get().unique}`, expiredAt)
  54.     }
  55.  
  56.     public async setMap(keyName: string, data: Record<string, any>, expiredAt: number): Promise<void> {
  57.         const ioRedis = this.redisConnect() as Redis
  58.         await ioRedis.hset(`${keyName}:${Publisher.get().unique}`, { payload: JSON.stringify(data) })
  59.         await ioRedis.expire(`${keyName}:${Publisher.get().unique}`, expiredAt)
  60.     }
  61. }
  62.  
  63. // Subscriber custom method
  64.  
  65. export class Subscriber {
  66.     private keyTo: string
  67.     private keyFrom: string
  68.     private uniqueId: string
  69.  
  70.     constructor(config: Readonly<ISubscriber>) {
  71.         this.keyTo = config.key
  72.         this.keyFrom = Publisher.get().key
  73.         this.uniqueId = Publisher.get().unique
  74.     }
  75.  
  76.     private redisConnect(): Redis {
  77.         const ioRedis = new IORedis({
  78.             host: process.env.REDIS_HOST,
  79.             port: +process.env.REDIS_PORT,
  80.             maxRetriesPerRequest: 50,
  81.             connectTimeout: 25000,
  82.             enableReadyCheck: true,
  83.             enableAutoPipelining: true
  84.         }) as Redis
  85.  
  86.         return ioRedis
  87.     }
  88.  
  89.     public async getString(keyName: string): Promise<any> {
  90.         if (this.keyTo == this.keyFrom) {
  91.             const ioRedis = this.redisConnect() as Redis
  92.             const response: string = await ioRedis.get(`${keyName}:${this.uniqueId}`)
  93.             if (response) {
  94.                 return Promise.resolve(response)
  95.             }
  96.             return {}
  97.         } else {
  98.             return Promise.reject(chalk.red(new Error(`invalid key Subscriber: ${this.keyTo} and Publisher: ${this.keyFrom}`)))
  99.         }
  100.     }
  101.  
  102.     public async getMap(keyName: string): Promise<any> {
  103.         if (this.keyTo == this.keyFrom) {
  104.             const ioRedis = this.redisConnect() as Redis
  105.             const response: Record<string, any> = await ioRedis.hgetall(`${keyName}:${this.uniqueId}`)
  106.             if (response) {
  107.                 return Promise.resolve(JSON.parse(response.payload))
  108.             }
  109.             return {}
  110.         } else {
  111.             return Promise.reject(chalk.red(new Error(`invalid key Subscriber: ${this.keyTo} and Publisher: ${this.keyFrom}`)))
  112.         }
  113.     }
  114. }
RAW Paste Data