1
0
mirror of https://github.com/redis/node-redis.git synced 2025-12-15 23:55:38 +03:00

fix(cluster): prevent infinite loop (#3078)

getRandomNode could end up in an infinite loop if
this.masters is empty and this.replicas is empty.

fixes: #3075
This commit is contained in:
Nikolay Karadzhov
2025-09-12 14:47:57 +03:00
committed by GitHub
parent e2702b63f2
commit 6eed1ee7ad
2 changed files with 12 additions and 2 deletions

View File

@@ -5,7 +5,6 @@ import RedisClusterSlots from './cluster-slots';
describe('RedisClusterSlots', () => { describe('RedisClusterSlots', () => {
describe('initialization', () => { describe('initialization', () => {
describe('clientSideCache validation', () => { describe('clientSideCache validation', () => {
const mockEmit = ((_event: string | symbol, ..._args: any[]): boolean => true) as EventEmitter['emit']; const mockEmit = ((_event: string | symbol, ..._args: any[]): boolean => true) as EventEmitter['emit'];
const clientSideCacheConfig = { ttl: 0, maxEntries: 0 }; const clientSideCacheConfig = { ttl: 0, maxEntries: 0 };
@@ -45,4 +44,14 @@ describe('RedisClusterSlots', () => {
}); });
}); });
}); });
describe('getRandomNode', ()=> {
it('should not enter infinite loop when no nodes', () => {
const slots = new RedisClusterSlots({
rootNodes: []
}, () => true)
slots.getRandomNode()
slots.getRandomNode()
});
});
}); });

View File

@@ -462,6 +462,7 @@ export default class RedisClusterSlots<
} }
*#iterateAllNodes() { *#iterateAllNodes() {
if(this.masters.length + this.replicas.length === 0) return
let i = Math.floor(Math.random() * (this.masters.length + this.replicas.length)); let i = Math.floor(Math.random() * (this.masters.length + this.replicas.length));
if (i < this.masters.length) { if (i < this.masters.length) {
do { do {
@@ -542,7 +543,7 @@ export default class RedisClusterSlots<
this.masters[index] : this.masters[index] :
this.replicas[index - this.masters.length], this.replicas[index - this.masters.length],
client = this.#createClient(node, false); client = this.#createClient(node, false);
this.pubSubNode = { this.pubSubNode = {
address: node.address, address: node.address,
client, client,