-
Notifications
You must be signed in to change notification settings - Fork 232
Expand file tree
/
Copy pathredis-adapter.ts
More file actions
109 lines (87 loc) · 3.16 KB
/
redis-adapter.ts
File metadata and controls
109 lines (87 loc) · 3.16 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
import { CacheClient } from '../@types/cache'
import { createLogger } from '../factories/logger-factory'
import { ICacheAdapter } from '../@types/adapters'
const debug = createLogger('redis-adapter')
export class RedisAdapter implements ICacheAdapter {
private connection: Promise<void>
prefixKey: boolean | string
public constructor(private readonly client: CacheClient) {
this.connection = client.connect()
this.connection.catch((error) => this.onClientError(error))
this.client
.on('connect', () => debug('connecting'))
.on('ready', () => debug('connected'))
.on('error', (error) => this.onClientError(error))
.on('reconnecting', () => {
debug('reconnecting')
this.connection = new Promise((resolve, reject) => {
const cleanup = () => {
this.client.removeListener('ready', onReady)
this.client.removeListener('error', onError)
}
const onError = (error: Error) => {
cleanup()
reject(error)
}
const onReady = () => {
cleanup()
resolve()
}
this.client.once('ready', onReady)
this.client.once('error', onError)
})
})
this.prefixKey = process.env.REDIS_PREFIX || false
}
private onClientError(error: Error) {
console.error('Unable to connect to Redis.', error)
// throw error
}
private addPrefixKey(key: string): string {
if(this.prefixKey) {
return `${this.prefixKey}:${key}`
}
return key
}
public async hasKey(key: string): Promise<boolean> {
await this.connection
debug('has %s key', key)
return Boolean(this.client.exists(this.addPrefixKey(key)))
}
public async getKey(key: string): Promise<string> {
await this.connection
debug('get %s key', key)
return this.client.get(this.addPrefixKey(key))
}
public async setKey(key: string, value: string): Promise<boolean> {
await this.connection
debug('get %s key', key)
return 'OK' === await this.client.set(this.addPrefixKey(key), value)
}
public async removeRangeByScoreFromSortedSet(key: string, min: number, max: number): Promise<number> {
await this.connection
debug('remove %d..%d range from sorted set %s', min, max, key)
return this.client.zRemRangeByScore(this.addPrefixKey(key), min, max)
}
public async getRangeFromSortedSet(key: string, min: number, max: number): Promise<string[]> {
await this.connection
debug('get %d..%d range from sorted set %s', min, max, key)
return this.client.zRange(this.addPrefixKey(key), min, max)
}
public async setKeyExpiry(key: string, expiry: number): Promise<void> {
await this.connection
debug('expire at %d from sorted set %s', expiry, key)
await this.client.expire(this.addPrefixKey(key), expiry)
}
public async addToSortedSet(
key: string,
set: Record<string, string>
): Promise<number> {
await this.connection
debug('add %o to sorted set %s', set, key)
const members = Object
.entries(set)
.map(([value, score]) => ({ score: Number(score), value }))
return this.client.zAdd(this.addPrefixKey(key), members)
}
}