Skip to content

Commit 6d8637c

Browse files
author
Artem
committed
fix validation error on UI side + rollback BE changes
1 parent 39741c6 commit 6d8637c

File tree

1 file changed

+115
-64
lines changed

1 file changed

+115
-64
lines changed

redisinsight/api/src/modules/redis/redis-connection.factory.ts

Lines changed: 115 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -164,9 +164,12 @@ export class RedisConnectionFactory {
164164
options: IRedisConnectionOptions,
165165
): Promise<Redis> {
166166
let tnl;
167+
let connection: Redis;
167168

168169
try {
169170
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;
170173

171174
if (database.ssh) {
172175
tnl = await this.sshTunnelProvider.createTunnel(database);
@@ -189,10 +192,9 @@ export class RedisConnectionFactory {
189192
config.port = tnl.serverAddress.port;
190193
}
191194

192-
const connection = new Redis({
195+
connection = new Redis({
193196
...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,
196198
});
197199
connection.on('error', (e): void => {
198200
this.logger.error('Failed connection to the redis database.', e);
@@ -205,7 +207,16 @@ export class RedisConnectionFactory {
205207
connection.on('ready', (): void => {
206208
lastError = null;
207209
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+
}
209220
});
210221
connection.on('reconnecting', (): void => {
211222
lastError = null;
@@ -216,6 +227,7 @@ export class RedisConnectionFactory {
216227
}
217228
}) as Redis;
218229
} catch (e) {
230+
connection?.disconnect?.();
219231
tnl?.close?.();
220232
throw e;
221233
}
@@ -232,43 +244,63 @@ export class RedisConnectionFactory {
232244
database: Database,
233245
options: IRedisConnectionOptions,
234246
): 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;
240248

241-
return new Promise((resolve, reject) => {
242-
try {
243-
let lastError: Error;
249+
try {
250+
const config = await this.getRedisClusterOptions(clientMetadata, database, options);
244251

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.');
270254
}
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+
}
272304
}
273305

274306
/**
@@ -282,34 +314,53 @@ export class RedisConnectionFactory {
282314
database: Database,
283315
options: IRedisConnectionOptions,
284316
): Promise<Redis> {
285-
const config = await this.getRedisSentinelOptions(clientMetadata, database, options);
317+
let connection: Redis;
286318

287-
return new Promise((resolve, reject) => {
288-
try {
289-
let lastError: Error;
319+
try {
320+
const config = await this.getRedisSentinelOptions(clientMetadata, database, options);
290321

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+
}
313364
}
314365

315366
/**

0 commit comments

Comments
 (0)