You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
lib/src/support/cache/RedisCache.ts

86 lines
2.6 KiB

import {Cache, Maybe} from '../../util'
import {Inject, Injectable} from '../../di'
import {Redis} from '../redis/Redis'
/**
* Redis-driven Cache implementation.
*/
@Injectable()
export class RedisCache extends Cache {
/** The Redis service. */
@Inject()
protected readonly redis!: Redis
async arrayPop(key: string): Promise<string | undefined> {
return this.redis.pipe()
.tap(redis => redis.lpop(key))
.resolve()
}
async arrayPush(key: string, value: string): Promise<void> {
await this.redis.pipe()
.tap(redis => redis.rpush(key, value))
.resolve()
}
async decrement(key: string, amount?: number): Promise<number | undefined> {
return this.redis.pipe()
.tap(redis => redis.decrby(key, amount ?? 1))
.resolve()
}
async increment(key: string, amount?: number): Promise<number | undefined> {
return this.redis.pipe()
.tap(redis => redis.incrby(key, amount ?? 1))
.resolve()
}
async drop(key: string): Promise<void> {
await this.redis.pipe()
.tap(redis => redis.del(key))
.resolve()
}
async fetch(key: string): Promise<string | undefined> {
return this.redis.pipe()
.tap(redis => redis.get(key))
.tap(value => value ?? undefined)
.resolve()
}
async has(key: string): Promise<boolean> {
return this.redis.pipe()
.tap(redis => redis.exists(key))
.tap(numExisting => numExisting > 0)
.resolve()
}
pop(key: string): Promise<Maybe<string>> {
return new Promise<Maybe<string>>((res, rej) => {
this.redis.pipe()
.tap(redis => {
redis.multi()
.get(key, (err, value) => {
if ( err ) {
rej(err)
} else {
res(value)
}
})
.del(key)
})
})
}
async put(key: string, value: string, expires?: Date): Promise<void> {
await this.redis.multi()
.tap(redis => redis.set(key, value))
.when(Boolean(expires), redis => {
const seconds = Math.round((expires!.getTime() - (new Date()).getTime()) / 1000) // eslint-disable-line @typescript-eslint/no-non-null-assertion
return redis.expire(key, seconds)
})
.tap(pipeline => pipeline.exec())
.resolve()
}
}