-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathredisClient.ts
109 lines (88 loc) · 2.96 KB
/
redisClient.ts
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 * as redis from 'redis';
export class RedisClient {
private client: redis.RedisClient;
private queueName = 'queue';
constructor(
private hostname: string,
private cacheExpiryTime: number,
private maxCapacity: number,
) {
this.client = redis.createClient(this.hostname);
}
get = (resource: string): Promise<string> => {
return new Promise((resolve, reject) => {
this.client.get(resource, async(error, value: string) => {
if (error) {
return reject(error);
}
await this.updateKeyPosition(resource);
return resolve(value)
});
});
}
atomicSet = async (resource: string, value: string): Promise<boolean> => {
const capacity = await this.lrange(this.queueName, 0, this.maxCapacity);
if (capacity.length === this.maxCapacity) {
await this.removeLeastUsedKey();
}
return new Promise((resolve) => {
const multi = this.client.multi();
multi.set(resource, value);
multi.expire(resource, this.cacheExpiryTime);
multi.exec(async(error) => {
if (error) {
return resolve(false);
}
await this.updateKeyPosition(resource);
return resolve(true);
});
});
}
lpush(listName: string, value: string) {
return new Promise((resolve, reject) => {
this.client.lpush(listName, value, (err: Error | null, reply: any) => {
if (err) {
return reject(err);
}
resolve(reply);
});
});
}
lrem(listName: string, count: number, value: string) {
return new Promise((resolve, reject) => {
this.client.lrem(listName, count, value, (err: Error | null, reply: any) => {
if (err) {
return reject(err);
}
resolve(reply);
});
});
}
rpop(listName: string) {
return new Promise((resolve, reject) => {
this.client.rpop(listName, (err: Error | null, reply: any) => {
if (err) {
return reject(err);
}
resolve(reply);
});
});
}
lrange(listName: string, start: number, stop: number): Promise<string[]> {
return new Promise((resolve, reject) => {
this.client.lrange(listName, start, stop, (err: Error | null, reply: any) => {
if (err) {
return reject(err);
}
resolve(reply);
});
});
}
async updateKeyPosition(key: string) {
await this.lrem(this.queueName, 0, key);
await this.lpush(this.queueName, key);
}
removeLeastUsedKey() {
return this.rpop(this.queueName);
}
}