3
3
import { ConfigService } from '@hashgraph/json-rpc-config-service/dist/services' ;
4
4
import { Logger } from 'pino' ;
5
5
import { Registry } from 'prom-client' ;
6
- import { createClient , RedisClientType } from 'redis' ;
6
+ import { RedisClientType } from 'redis' ;
7
7
8
8
import { Utils } from '../../../utils' ;
9
- import { RedisCacheError } from '../../errors/RedisCacheError' ;
10
9
import { IRedisCacheClient } from './IRedisCacheClient' ;
11
10
12
11
/**
@@ -41,66 +40,16 @@ export class RedisCache implements IRedisCacheClient {
41
40
*/
42
41
private readonly client : RedisClientType ;
43
42
44
- /**
45
- * Boolean showing if the connection to the Redis client has finished.
46
- * @private
47
- */
48
- private connected : Promise < boolean > ;
49
-
50
43
/**
51
44
* Creates an instance of `RedisCache`.
52
45
*
53
46
* @param {Logger } logger - The logger instance.
54
47
* @param {Registry } register - The metrics registry.
55
48
*/
56
- public constructor ( logger : Logger , register : Registry ) {
49
+ public constructor ( logger : Logger , register : Registry , client : RedisClientType ) {
57
50
this . logger = logger ;
58
51
this . register = register ;
59
-
60
- const redisUrl = ConfigService . get ( 'REDIS_URL' ) ! ;
61
- const reconnectDelay = ConfigService . get ( 'REDIS_RECONNECT_DELAY_MS' ) ;
62
- this . client = createClient ( {
63
- url : redisUrl ,
64
- socket : {
65
- reconnectStrategy : ( retries : number ) => {
66
- const delay = retries * reconnectDelay ;
67
- logger . warn ( `Trying to reconnect with Redis, retry #${ retries } . Delay is ${ delay } ms...` ) ;
68
- return delay ;
69
- } ,
70
- } ,
71
- } ) ;
72
- this . connected = this . client
73
- . connect ( )
74
- . then ( ( ) => true )
75
- . catch ( ( error ) => {
76
- this . logger . error ( error , 'Redis connection could not be established!' ) ;
77
- return false ;
78
- } ) ;
79
- this . client . on ( 'ready' , async ( ) => {
80
- this . connected = Promise . resolve ( true ) ;
81
- const connections = await this . getNumberOfConnections ( ) . catch ( ( error ) => {
82
- this . logger . error ( error ) ;
83
- return 0 ;
84
- } ) ;
85
- logger . info ( `Connected to Redis server (${ redisUrl } ) successfully! Number of connections: ${ connections } ` ) ;
86
- } ) ;
87
- this . client . on ( 'end' , ( ) => {
88
- this . connected = Promise . resolve ( false ) ;
89
- logger . info ( 'Disconnected from Redis server!' ) ;
90
- } ) ;
91
- this . client . on ( 'error' , ( error ) => {
92
- this . connected = Promise . resolve ( false ) ;
93
- const redisError = new RedisCacheError ( error ) ;
94
- if ( redisError . isSocketClosed ( ) ) {
95
- logger . error ( `Error occurred with Redis Connection when closing socket: ${ redisError . message } ` ) ;
96
- } else {
97
- logger . error ( `Error occurred with Redis Connection: ${ redisError . fullError } ` ) ;
98
- }
99
- } ) ;
100
- }
101
-
102
- async getConnectedClient ( ) : Promise < RedisClientType > {
103
- return this . isConnected ( ) . then ( ( ) => this . client ) ;
52
+ this . client = client ;
104
53
}
105
54
106
55
/**
@@ -111,8 +60,7 @@ export class RedisCache implements IRedisCacheClient {
111
60
* @returns The cached value or null if not found.
112
61
*/
113
62
async get ( key : string , callingMethod : string ) : Promise < any > {
114
- const client = await this . getConnectedClient ( ) ;
115
- const result = await client . get ( key ) ;
63
+ const result = await this . client . get ( key ) ;
116
64
if ( result ) {
117
65
if ( this . logger . isLevelEnabled ( 'trace' ) ) {
118
66
const censoredKey = key . replace ( Utils . IP_ADDRESS_REGEX , '<REDACTED>' ) ;
@@ -135,13 +83,12 @@ export class RedisCache implements IRedisCacheClient {
135
83
* @returns A Promise that resolves when the value is cached.
136
84
*/
137
85
async set ( key : string , value : any , callingMethod : string , ttl ?: number ) : Promise < void > {
138
- const client = await this . getConnectedClient ( ) ;
139
86
const serializedValue = JSON . stringify ( value ) ;
140
87
const resolvedTtl = ttl ?? this . options . ttl ; // in milliseconds
141
88
if ( resolvedTtl > 0 ) {
142
- await client . set ( key , serializedValue , { PX : resolvedTtl } ) ;
89
+ await this . client . set ( key , serializedValue , { PX : resolvedTtl } ) ;
143
90
} else {
144
- await client . set ( key , serializedValue ) ;
91
+ await this . client . set ( key , serializedValue ) ;
145
92
}
146
93
147
94
const censoredKey = key . replace ( Utils . IP_ADDRESS_REGEX , '<REDACTED>' ) ;
@@ -163,15 +110,14 @@ export class RedisCache implements IRedisCacheClient {
163
110
* @returns A Promise that resolves when the values are cached.
164
111
*/
165
112
async multiSet ( keyValuePairs : Record < string , any > , callingMethod : string ) : Promise < void > {
166
- const client = await this . getConnectedClient ( ) ;
167
113
// Serialize values
168
114
const serializedKeyValuePairs : Record < string , string > = { } ;
169
115
for ( const [ key , value ] of Object . entries ( keyValuePairs ) ) {
170
116
serializedKeyValuePairs [ key ] = JSON . stringify ( value ) ;
171
117
}
172
118
173
119
// Perform mSet operation
174
- await client . mSet ( serializedKeyValuePairs ) ;
120
+ await this . client . mSet ( serializedKeyValuePairs ) ;
175
121
176
122
// Log the operation
177
123
const entriesLength = Object . keys ( keyValuePairs ) . length ;
@@ -189,10 +135,9 @@ export class RedisCache implements IRedisCacheClient {
189
135
* @returns A Promise that resolves when the values are cached.
190
136
*/
191
137
async pipelineSet ( keyValuePairs : Record < string , any > , callingMethod : string , ttl ?: number ) : Promise < void > {
192
- const client = await this . getConnectedClient ( ) ;
193
138
const resolvedTtl = ttl ?? this . options . ttl ; // in milliseconds
194
139
195
- const pipeline = client . multi ( ) ;
140
+ const pipeline = this . client . multi ( ) ;
196
141
197
142
for ( const [ key , value ] of Object . entries ( keyValuePairs ) ) {
198
143
const serializedValue = JSON . stringify ( value ) ;
@@ -217,66 +162,13 @@ export class RedisCache implements IRedisCacheClient {
217
162
* @returns A Promise that resolves when the value is deleted from the cache.
218
163
*/
219
164
async delete ( key : string , callingMethod : string ) : Promise < void > {
220
- const client = await this . getConnectedClient ( ) ;
221
- await client . del ( key ) ;
165
+ await this . client . del ( key ) ;
222
166
if ( this . logger . isLevelEnabled ( 'trace' ) ) {
223
167
this . logger . trace ( `delete cache for ${ key } on ${ callingMethod } call` ) ;
224
168
}
225
169
// TODO: add metrics
226
170
}
227
171
228
- /**
229
- * Clears the entire cache.
230
- *
231
- * @returns {Promise<void> } A Promise that resolves when the cache is cleared.
232
- */
233
- async clear ( ) : Promise < void > {
234
- const client = await this . getConnectedClient ( ) ;
235
- await client . flushAll ( ) ;
236
- }
237
-
238
- /**
239
- * Checks if the client is connected to the Redis server.
240
- *
241
- * @returns {Promise<boolean> } A Promise that resolves to true if the client is connected, false otherwise.
242
- */
243
- async isConnected ( ) : Promise < boolean > {
244
- return this . connected ;
245
- }
246
-
247
- /**
248
- * Retrieves the number of connections to the Redis server.
249
- *
250
- * @returns {Promise<number> } A Promise that resolves to the number of connections.
251
- * @throws {Error } If an error occurs while retrieving the number of connections.
252
- */
253
- async getNumberOfConnections ( ) : Promise < number > {
254
- const client = await this . getConnectedClient ( ) ;
255
- const clientList = await client . clientList ( ) ;
256
- return clientList . length ;
257
- }
258
-
259
- /**
260
- * Connects the client to the Redis server.
261
- *
262
- * @returns {Promise<void> } A Promise that resolves when the client is connected.
263
- * @throws {Error } If an error occurs while connecting to Redis.
264
- */
265
- async connect ( ) : Promise < void > {
266
- await this . client . connect ( ) ;
267
- }
268
-
269
- /**
270
- * Disconnects the client from the Redis server.
271
- *
272
- * @returns {Promise<void> } A Promise that resolves when the client is disconnected.
273
- * @throws {Error } If an error occurs while disconnecting from Redis.
274
- */
275
- async disconnect ( ) : Promise < void > {
276
- const client = await this . getConnectedClient ( ) ;
277
- await client . quit ( ) ;
278
- }
279
-
280
172
/**
281
173
* Increments a value in the cache.
282
174
*
@@ -286,8 +178,7 @@ export class RedisCache implements IRedisCacheClient {
286
178
* @returns The value of the key after incrementing
287
179
*/
288
180
async incrBy ( key : string , amount : number , callingMethod : string ) : Promise < number > {
289
- const client = await this . getConnectedClient ( ) ;
290
- const result = await client . incrBy ( key , amount ) ;
181
+ const result = await this . client . incrBy ( key , amount ) ;
291
182
if ( this . logger . isLevelEnabled ( 'trace' ) ) {
292
183
this . logger . trace ( `incrementing ${ key } by ${ amount } on ${ callingMethod } call` ) ;
293
184
}
@@ -304,8 +195,7 @@ export class RedisCache implements IRedisCacheClient {
304
195
* @returns The list of elements in the range
305
196
*/
306
197
async lRange ( key : string , start : number , end : number , callingMethod : string ) : Promise < any [ ] > {
307
- const client = await this . getConnectedClient ( ) ;
308
- const result = await client . lRange ( key , start , end ) ;
198
+ const result = await this . client . lRange ( key , start , end ) ;
309
199
if ( this . logger . isLevelEnabled ( 'trace' ) ) {
310
200
this . logger . trace ( `retrieving range [${ start } :${ end } ] from ${ key } on ${ callingMethod } call` ) ;
311
201
}
@@ -321,9 +211,8 @@ export class RedisCache implements IRedisCacheClient {
321
211
* @returns The length of the list after pushing
322
212
*/
323
213
async rPush ( key : string , value : any , callingMethod : string ) : Promise < number > {
324
- const client = await this . getConnectedClient ( ) ;
325
214
const serializedValue = JSON . stringify ( value ) ;
326
- const result = await client . rPush ( key , serializedValue ) ;
215
+ const result = await this . client . rPush ( key , serializedValue ) ;
327
216
if ( this . logger . isLevelEnabled ( 'trace' ) ) {
328
217
this . logger . trace ( `pushing ${ serializedValue } to ${ key } on ${ callingMethod } call` ) ;
329
218
}
@@ -337,11 +226,19 @@ export class RedisCache implements IRedisCacheClient {
337
226
* @returns The list of keys matching the pattern
338
227
*/
339
228
async keys ( pattern : string , callingMethod : string ) : Promise < string [ ] > {
340
- const client = await this . getConnectedClient ( ) ;
341
- const result = await client . keys ( pattern ) ;
229
+ const result = await this . client . keys ( pattern ) ;
342
230
if ( this . logger . isLevelEnabled ( 'trace' ) ) {
343
231
this . logger . trace ( `retrieving keys matching ${ pattern } on ${ callingMethod } call` ) ;
344
232
}
345
233
return result ;
346
234
}
235
+
236
+ /**
237
+ * Clears the entire cache.
238
+ *
239
+ * @returns {Promise<void> } A Promise that resolves when the cache is cleared.
240
+ */
241
+ async clear ( ) : Promise < void > {
242
+ await this . client . flushAll ( ) ;
243
+ }
347
244
}
0 commit comments