🔧 fix: Redis cluster connection errors and configuration (#9016)

- Fix ioredis cluster initialization to use proper node array format
- Fix reconnectOnError to return numeric delay instead of boolean
- Fix keyv redis cluster configuration to use proper URL objects
- Resolves "undefinedms" reconnection delay errors
This commit is contained in:
Theo N. Truong 2025-08-12 20:23:29 -06:00 committed by GitHub
parent a199b87478
commit 4799593e1a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -38,7 +38,7 @@ if (cacheConfig.USE_REDIS) {
const targetError = 'READONLY'; const targetError = 'READONLY';
if (err.message.includes(targetError)) { if (err.message.includes(targetError)) {
logger.warn('ioredis reconnecting due to READONLY error'); logger.warn('ioredis reconnecting due to READONLY error');
return true; return 2; // Return retry delay instead of boolean
} }
return false; return false;
}, },
@ -50,24 +50,27 @@ if (cacheConfig.USE_REDIS) {
ioredisClient = ioredisClient =
urls.length === 1 urls.length === 1
? new IoRedis(cacheConfig.REDIS_URI, redisOptions) ? new IoRedis(cacheConfig.REDIS_URI, redisOptions)
: new IoRedis.Cluster(cacheConfig.REDIS_URI, { : new IoRedis.Cluster(
redisOptions, urls.map((url) => ({ host: url.hostname, port: parseInt(url.port, 10) || 6379 })),
clusterRetryStrategy: (times) => { {
if ( redisOptions,
cacheConfig.REDIS_RETRY_MAX_ATTEMPTS > 0 && clusterRetryStrategy: (times) => {
times > cacheConfig.REDIS_RETRY_MAX_ATTEMPTS if (
) { cacheConfig.REDIS_RETRY_MAX_ATTEMPTS > 0 &&
logger.error( times > cacheConfig.REDIS_RETRY_MAX_ATTEMPTS
`ioredis cluster giving up after ${cacheConfig.REDIS_RETRY_MAX_ATTEMPTS} reconnection attempts`, ) {
); logger.error(
return null; `ioredis cluster giving up after ${cacheConfig.REDIS_RETRY_MAX_ATTEMPTS} reconnection attempts`,
} );
const delay = Math.min(times * 100, cacheConfig.REDIS_RETRY_MAX_DELAY); return null;
logger.info(`ioredis cluster reconnecting... attempt ${times}, delay ${delay}ms`); }
return delay; const delay = Math.min(times * 100, cacheConfig.REDIS_RETRY_MAX_DELAY);
logger.info(`ioredis cluster reconnecting... attempt ${times}, delay ${delay}ms`);
return delay;
},
enableOfflineQueue: cacheConfig.REDIS_ENABLE_OFFLINE_QUEUE,
}, },
enableOfflineQueue: cacheConfig.REDIS_ENABLE_OFFLINE_QUEUE, );
});
ioredisClient.on('error', (err) => { ioredisClient.on('error', (err) => {
logger.error('ioredis client error:', err); logger.error('ioredis client error:', err);
@ -148,7 +151,7 @@ if (cacheConfig.USE_REDIS) {
urls.length === 1 urls.length === 1
? createClient({ url: cacheConfig.REDIS_URI, ...redisOptions }) ? createClient({ url: cacheConfig.REDIS_URI, ...redisOptions })
: createCluster({ : createCluster({
rootNodes: cacheConfig.REDIS_URI.split(',').map((url) => ({ url })), rootNodes: urls.map((url) => ({ url: url.href })),
defaults: redisOptions, defaults: redisOptions,
}); });