📱 refactor: Redis Client Error Logging and Ping only when Ready (#8671)

* 📱 refactor: Redis Client Error Logging and Ping only when Ready

* chore: intellisense for warning comment for Keyv Redis client regarding prefix support
This commit is contained in:
Danny Avila 2025-07-25 12:33:05 -04:00 committed by GitHub
parent 26f23c6aaf
commit 5251246313
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -1,6 +1,7 @@
const IoRedis = require('ioredis'); const IoRedis = require('ioredis');
const { cacheConfig } = require('./cacheConfig'); const { logger } = require('@librechat/data-schemas');
const { createClient, createCluster } = require('@keyv/redis'); const { createClient, createCluster } = require('@keyv/redis');
const { cacheConfig } = require('./cacheConfig');
const GLOBAL_PREFIX_SEPARATOR = '::'; const GLOBAL_PREFIX_SEPARATOR = '::';
@ -25,20 +26,37 @@ if (cacheConfig.USE_REDIS) {
? new IoRedis(cacheConfig.REDIS_URI, redisOptions) ? new IoRedis(cacheConfig.REDIS_URI, redisOptions)
: new IoRedis.Cluster(cacheConfig.REDIS_URI, { redisOptions }); : new IoRedis.Cluster(cacheConfig.REDIS_URI, { redisOptions });
// Pinging the Redis server to keep the connection alive (if enabled) ioredisClient.on('error', (err) => {
logger.error('ioredis client error:', err);
});
/** Ping Interval to keep the Redis server connection alive (if enabled) */
let pingInterval = null; let pingInterval = null;
const clearPingInterval = () => {
if (pingInterval) {
clearInterval(pingInterval);
pingInterval = null;
}
};
if (cacheConfig.REDIS_PING_INTERVAL > 0) { if (cacheConfig.REDIS_PING_INTERVAL > 0) {
pingInterval = setInterval(() => ioredisClient.ping(), cacheConfig.REDIS_PING_INTERVAL * 1000); pingInterval = setInterval(() => {
ioredisClient.on('close', () => clearInterval(pingInterval)); if (ioredisClient && ioredisClient.status === 'ready') {
ioredisClient.on('end', () => clearInterval(pingInterval)); ioredisClient.ping();
}
}, cacheConfig.REDIS_PING_INTERVAL * 1000);
ioredisClient.on('close', clearPingInterval);
ioredisClient.on('end', clearPingInterval);
} }
} }
/** @type {import('@keyv/redis').RedisClient | import('@keyv/redis').RedisCluster | null} */ /** @type {import('@keyv/redis').RedisClient | import('@keyv/redis').RedisCluster | null} */
let keyvRedisClient = null; let keyvRedisClient = null;
if (cacheConfig.USE_REDIS) { if (cacheConfig.USE_REDIS) {
// ** WARNING ** Keyv Redis client does not support Prefix like ioredis above. /**
// The prefix feature will be handled by the Keyv-Redis store in cacheFactory.js * ** WARNING ** Keyv Redis client does not support Prefix like ioredis above.
* The prefix feature will be handled by the Keyv-Redis store in cacheFactory.js
*/
const redisOptions = { username, password, socket: { tls: ca != null, ca } }; const redisOptions = { username, password, socket: { tls: ca != null, ca } };
keyvRedisClient = keyvRedisClient =
@ -51,15 +69,27 @@ if (cacheConfig.USE_REDIS) {
keyvRedisClient.setMaxListeners(cacheConfig.REDIS_MAX_LISTENERS); keyvRedisClient.setMaxListeners(cacheConfig.REDIS_MAX_LISTENERS);
// Pinging the Redis server to keep the connection alive (if enabled) keyvRedisClient.on('error', (err) => {
logger.error('@keyv/redis client error:', err);
});
/** Ping Interval to keep the Redis server connection alive (if enabled) */
let pingInterval = null; let pingInterval = null;
const clearPingInterval = () => {
if (pingInterval) {
clearInterval(pingInterval);
pingInterval = null;
}
};
if (cacheConfig.REDIS_PING_INTERVAL > 0) { if (cacheConfig.REDIS_PING_INTERVAL > 0) {
pingInterval = setInterval( pingInterval = setInterval(() => {
() => keyvRedisClient.ping(), if (keyvRedisClient && keyvRedisClient.isReady) {
cacheConfig.REDIS_PING_INTERVAL * 1000, keyvRedisClient.ping();
); }
keyvRedisClient.on('disconnect', () => clearInterval(pingInterval)); }, cacheConfig.REDIS_PING_INTERVAL * 1000);
keyvRedisClient.on('end', () => clearInterval(pingInterval)); keyvRedisClient.on('disconnect', clearPingInterval);
keyvRedisClient.on('end', clearPingInterval);
} }
} }