import {Inject, Singleton} from '../../di' import {Config} from '../../service/Config' import * as IORedis from 'ioredis' import {RedisOptions} from 'ioredis' import {Logging} from '../../service/Logging' import {Unit} from '../../lifecycle/Unit' import {AsyncPipe} from '../../util' export {RedisOptions} from 'ioredis' /** * Unit that loads configuration for and manages instantiation * of an IORedis connection. */ @Singleton() export class Redis extends Unit { /** The config service. */ @Inject() protected readonly config!: Config /** The loggers. */ @Inject() protected readonly logging!: Logging /** * The instantiated connection, if one exists. * @private */ private connection?: IORedis.Redis async up(): Promise { this.logging.info('Attempting initial connection to Redis...') this.logging.debug('Config:') this.logging.debug(Config) this.logging.debug(this.config) await this.getConnection() } async down(): Promise { this.logging.info('Disconnecting Redis...') if ( this.connection?.status === 'ready' ) { await this.connection.disconnect() } } /** * Get the IORedis connection instance. */ public async getConnection(): Promise { if ( !this.connection ) { const options = this.config.get('redis.connection') as RedisOptions this.logging.verbose(options) this.connection = new IORedis(options) } return this.connection } /** * Get the IORedis connection in an AsyncPipe. */ public pipe(): AsyncPipe { return new AsyncPipe(() => this.getConnection()) } /** * Get an IORedis.Pipeline instance in an AsyncPipe. */ public multi(): AsyncPipe { return this.pipe() .tap(redis => { return redis.multi() }) } }