86 lines
2.6 KiB
TypeScript
86 lines
2.6 KiB
TypeScript
|
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(((new Date()).getTime() - expires!.getTime()) / 1000) // eslint-disable-line @typescript-eslint/no-non-null-assertion
|
||
|
return redis.expire(key, seconds)
|
||
|
})
|
||
|
.tap(pipeline => pipeline.exec())
|
||
|
.resolve()
|
||
|
}
|
||
|
}
|