@@ -164,9 +164,12 @@ export class RedisConnectionFactory {
164
164
options : IRedisConnectionOptions ,
165
165
) : Promise < Redis > {
166
166
let tnl ;
167
+ let connection : Redis ;
167
168
168
169
try {
169
170
const config = await this . getRedisOptions ( clientMetadata , database , options ) ;
171
+ // cover cases when we are connecting to sentinel using standalone client to discover master groups
172
+ const dbIndex = config . db > 0 && ! database . sentinelMaster ? config . db : 0 ;
170
173
171
174
if ( database . ssh ) {
172
175
tnl = await this . sshTunnelProvider . createTunnel ( database ) ;
@@ -189,10 +192,9 @@ export class RedisConnectionFactory {
189
192
config . port = tnl . serverAddress . port ;
190
193
}
191
194
192
- const connection = new Redis ( {
195
+ connection = new Redis ( {
193
196
...config ,
194
- // cover cases when we are connecting to sentinel as to standalone to discover master groups
195
- db : config . db > 0 && ! database . sentinelMaster ? config . db : 0 ,
197
+ db : 0 ,
196
198
} ) ;
197
199
connection . on ( 'error' , ( e ) : void => {
198
200
this . logger . error ( 'Failed connection to the redis database.' , e ) ;
@@ -205,7 +207,16 @@ export class RedisConnectionFactory {
205
207
connection . on ( 'ready' , ( ) : void => {
206
208
lastError = null ;
207
209
this . logger . log ( 'Successfully connected to the redis database' ) ;
208
- resolve ( connection ) ;
210
+
211
+ // manual switch to particular logical db
212
+ // since ioredis doesn't handle "select" command error during connection
213
+ if ( dbIndex > 0 ) {
214
+ connection . select ( dbIndex )
215
+ . then ( ( ) => resolve ( connection ) )
216
+ . catch ( reject ) ;
217
+ } else {
218
+ resolve ( connection ) ;
219
+ }
209
220
} ) ;
210
221
connection . on ( 'reconnecting' , ( ) : void => {
211
222
lastError = null ;
@@ -216,6 +227,7 @@ export class RedisConnectionFactory {
216
227
}
217
228
} ) as Redis ;
218
229
} catch ( e ) {
230
+ connection ?. disconnect ?.( ) ;
219
231
tnl ?. close ?.( ) ;
220
232
throw e ;
221
233
}
@@ -232,43 +244,63 @@ export class RedisConnectionFactory {
232
244
database : Database ,
233
245
options : IRedisConnectionOptions ,
234
246
) : Promise < Cluster > {
235
- const config = await this . getRedisClusterOptions ( clientMetadata , database , options ) ;
236
-
237
- if ( database . ssh ) {
238
- throw new Error ( 'SSH is unsupported for cluster databases.' ) ;
239
- }
247
+ let connection : Cluster ;
240
248
241
- return new Promise ( ( resolve , reject ) => {
242
- try {
243
- let lastError : Error ;
249
+ try {
250
+ const config = await this . getRedisClusterOptions ( clientMetadata , database , options ) ;
244
251
245
- const cluster = new Cluster ( [ {
246
- host : database . host ,
247
- port : database . port ,
248
- } ] . concat ( database . nodes ) , {
249
- ...config ,
250
- } ) ;
251
- cluster . on ( 'error' , ( e ) : void => {
252
- this . logger . error ( 'Failed connection to the redis oss cluster' , e ) ;
253
- lastError = ! isEmpty ( e . lastNodeError ) ? e . lastNodeError : e ;
254
- } ) ;
255
- cluster . on ( 'end' , ( ) : void => {
256
- this . logger . error ( ERROR_MESSAGES . UNABLE_TO_ESTABLISH_CONNECTION , lastError ) ;
257
- reject ( lastError || new InternalServerErrorException ( ERROR_MESSAGES . SERVER_CLOSED_CONNECTION ) ) ;
258
- } ) ;
259
- cluster . on ( 'ready' , ( ) : void => {
260
- lastError = null ;
261
- this . logger . log ( 'Successfully connected to the redis oss cluster.' ) ;
262
- resolve ( cluster ) ;
263
- } ) ;
264
- cluster . on ( 'reconnecting' , ( ) : void => {
265
- lastError = null ;
266
- this . logger . log ( ERROR_MESSAGES . RECONNECTING_TO_DATABASE ) ;
267
- } ) ;
268
- } catch ( e ) {
269
- reject ( e ) ;
252
+ if ( database . ssh ) {
253
+ throw new Error ( 'SSH is unsupported for cluster databases.' ) ;
270
254
}
271
- } ) ;
255
+
256
+ return await ( new Promise ( ( resolve , reject ) => {
257
+ try {
258
+ let lastError : Error ;
259
+
260
+ connection = new Cluster ( [ {
261
+ host : database . host ,
262
+ port : database . port ,
263
+ } ] . concat ( database . nodes ) , {
264
+ ...config ,
265
+ redisOptions : {
266
+ ...config . redisOptions ,
267
+ db : 0 ,
268
+ } ,
269
+ } ) ;
270
+ connection . on ( 'error' , ( e ) : void => {
271
+ this . logger . error ( 'Failed connection to the redis oss cluster' , e ) ;
272
+ lastError = ! isEmpty ( e . lastNodeError ) ? e . lastNodeError : e ;
273
+ } ) ;
274
+ connection . on ( 'end' , ( ) : void => {
275
+ this . logger . error ( ERROR_MESSAGES . UNABLE_TO_ESTABLISH_CONNECTION , lastError ) ;
276
+ reject ( lastError || new InternalServerErrorException ( ERROR_MESSAGES . SERVER_CLOSED_CONNECTION ) ) ;
277
+ } ) ;
278
+ connection . on ( 'ready' , ( ) : void => {
279
+ lastError = null ;
280
+ this . logger . log ( 'Successfully connected to the redis oss cluster.' ) ;
281
+
282
+ // manual switch to particular logical db
283
+ // since ioredis doesn't handle "select" command error during connection
284
+ if ( config . redisOptions . db > 0 ) {
285
+ connection . select ( config . redisOptions . db )
286
+ . then ( ( ) => resolve ( connection ) )
287
+ . catch ( reject ) ;
288
+ } else {
289
+ resolve ( connection ) ;
290
+ }
291
+ } ) ;
292
+ connection . on ( 'reconnecting' , ( ) : void => {
293
+ lastError = null ;
294
+ this . logger . log ( ERROR_MESSAGES . RECONNECTING_TO_DATABASE ) ;
295
+ } ) ;
296
+ } catch ( e ) {
297
+ reject ( e ) ;
298
+ }
299
+ } ) ) ;
300
+ } catch ( e ) {
301
+ connection ?. disconnect ?.( ) ;
302
+ throw e ;
303
+ }
272
304
}
273
305
274
306
/**
@@ -282,34 +314,53 @@ export class RedisConnectionFactory {
282
314
database : Database ,
283
315
options : IRedisConnectionOptions ,
284
316
) : Promise < Redis > {
285
- const config = await this . getRedisSentinelOptions ( clientMetadata , database , options ) ;
317
+ let connection : Redis ;
286
318
287
- return new Promise ( ( resolve , reject ) => {
288
- try {
289
- let lastError : Error ;
319
+ try {
320
+ const config = await this . getRedisSentinelOptions ( clientMetadata , database , options ) ;
290
321
291
- const client = new Redis ( config ) ;
292
- client . on ( 'error' , ( e ) : void => {
293
- this . logger . error ( 'Failed connection to the redis oss sentinel' , e ) ;
294
- lastError = e ;
295
- } ) ;
296
- client . on ( 'end' , ( ) : void => {
297
- this . logger . error ( ERROR_MESSAGES . UNABLE_TO_ESTABLISH_CONNECTION , lastError ) ;
298
- reject ( lastError || new InternalServerErrorException ( ERROR_MESSAGES . SERVER_CLOSED_CONNECTION ) ) ;
299
- } ) ;
300
- client . on ( 'ready' , ( ) : void => {
301
- lastError = null ;
302
- this . logger . log ( 'Successfully connected to the redis oss sentinel.' ) ;
303
- resolve ( client ) ;
304
- } ) ;
305
- client . on ( 'reconnecting' , ( ) : void => {
306
- lastError = null ;
307
- this . logger . log ( ERROR_MESSAGES . RECONNECTING_TO_DATABASE ) ;
308
- } ) ;
309
- } catch ( e ) {
310
- reject ( e ) ;
311
- }
312
- } ) ;
322
+ return await ( new Promise ( ( resolve , reject ) => {
323
+ try {
324
+ let lastError : Error ;
325
+
326
+ connection = new Redis ( {
327
+ ...config ,
328
+ db : 0 ,
329
+ } ) ;
330
+ connection . on ( 'error' , ( e ) : void => {
331
+ this . logger . error ( 'Failed connection to the redis oss sentinel' , e ) ;
332
+ lastError = e ;
333
+ } ) ;
334
+ connection . on ( 'end' , ( ) : void => {
335
+ this . logger . error ( ERROR_MESSAGES . UNABLE_TO_ESTABLISH_CONNECTION , lastError ) ;
336
+ reject ( lastError || new InternalServerErrorException ( ERROR_MESSAGES . SERVER_CLOSED_CONNECTION ) ) ;
337
+ } ) ;
338
+ connection . on ( 'ready' , ( ) : void => {
339
+ lastError = null ;
340
+ this . logger . log ( 'Successfully connected to the redis oss sentinel.' ) ;
341
+
342
+ // manual switch to particular logical db
343
+ // since ioredis doesn't handle "select" command error during connection
344
+ if ( config . db > 0 ) {
345
+ connection . select ( config . db )
346
+ . then ( ( ) => resolve ( connection ) )
347
+ . catch ( reject ) ;
348
+ } else {
349
+ resolve ( connection ) ;
350
+ }
351
+ } ) ;
352
+ connection . on ( 'reconnecting' , ( ) : void => {
353
+ lastError = null ;
354
+ this . logger . log ( ERROR_MESSAGES . RECONNECTING_TO_DATABASE ) ;
355
+ } ) ;
356
+ } catch ( e ) {
357
+ reject ( e ) ;
358
+ }
359
+ } ) ) ;
360
+ } catch ( e ) {
361
+ connection ?. disconnect ?.( ) ;
362
+ throw e ;
363
+ }
313
364
}
314
365
315
366
/**
0 commit comments