2021-08-24 04:51:53 +00:00
|
|
|
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'
|
2022-03-29 07:30:48 +00:00
|
|
|
import {AsyncPipe, Collection} from '../../util'
|
2021-08-24 04:51:53 +00:00
|
|
|
|
|
|
|
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
|
|
|
|
|
2022-03-29 07:30:48 +00:00
|
|
|
/**
|
|
|
|
* Collection of all Redis connections opened by this service.
|
|
|
|
* We keep track of these here so we can make sure -all- of them get closed
|
|
|
|
* when the framework tries to shut down.
|
|
|
|
* @private
|
|
|
|
*/
|
|
|
|
private spawnedConnections: Collection<IORedis.Redis> = new Collection()
|
|
|
|
|
2021-08-24 04:51:53 +00:00
|
|
|
async up(): Promise<void> {
|
|
|
|
this.logging.info('Attempting initial connection to Redis...')
|
|
|
|
this.logging.debug(this.config)
|
|
|
|
await this.getConnection()
|
|
|
|
}
|
|
|
|
|
|
|
|
async down(): Promise<void> {
|
|
|
|
this.logging.info('Disconnecting Redis...')
|
2022-03-29 07:30:48 +00:00
|
|
|
await this.spawnedConnections
|
|
|
|
.where('status', '=', 'ready')
|
|
|
|
.awaitMapCall('disconnect')
|
2021-08-24 04:51:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get the IORedis connection instance.
|
|
|
|
*/
|
|
|
|
public async getConnection(): Promise<IORedis.Redis> {
|
|
|
|
if ( !this.connection ) {
|
2022-01-27 01:37:54 +00:00
|
|
|
this.connection = await this.getNewConnection()
|
2021-08-24 04:51:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return this.connection
|
|
|
|
}
|
|
|
|
|
2022-01-27 01:37:54 +00:00
|
|
|
/**
|
|
|
|
* Get a new IORedis connection instance.
|
|
|
|
*/
|
|
|
|
public async getNewConnection(): Promise<IORedis.Redis> {
|
|
|
|
const options = this.config.get('redis.connection') as RedisOptions
|
2022-03-29 07:30:48 +00:00
|
|
|
const inst = new IORedis(options)
|
|
|
|
this.spawnedConnections.push(inst)
|
|
|
|
return inst
|
2022-01-27 01:37:54 +00:00
|
|
|
}
|
|
|
|
|
2021-08-24 04:51:53 +00:00
|
|
|
/**
|
|
|
|
* Get the IORedis connection in an AsyncPipe.
|
|
|
|
*/
|
|
|
|
public pipe(): AsyncPipe<IORedis.Redis> {
|
|
|
|
return new AsyncPipe<IORedis.Redis>(() => this.getConnection())
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get an IORedis.Pipeline instance in an AsyncPipe.
|
|
|
|
*/
|
|
|
|
public multi(): AsyncPipe<IORedis.Pipeline> {
|
|
|
|
return this.pipe()
|
|
|
|
.tap(redis => {
|
|
|
|
return redis.multi()
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|