Habíamos implementado una retry_strategy que emite un error después de una cierta cantidad de reintentos. Esto luego se enviaría al controlador de encendido ('error') de Redis para que se registre y salga de la aplicación. Al actualizar nuestra biblioteca redis de 2.4.2
a 2.6.2
notamos que este comportamiento ya no es el mismo.
Caso de repro:
const redis = require('redis');
const MAX_ATTEMPTS = 10;
var client = redis.createClient(port, host, {
retry_strategy: redisRetryStrategy
});
client.on('error', onError);
function OnError(err) {
console.log(err);
throw new Error('SHUTDOWN THE APP, REDIS IS NOT RESPONDING??');
}
function redisRetryStrategy(host, options) {
if (options.attempt >= MAX_ATTEMPTS) {
// Stop reconnecting after reaching the maximum number of attempts
return new Error('Maximum redis reconnect attempts reached');
}
return 1000; // Schedule next reconnection attempt after 1 sec.
}
En realidad, esto es algo que se hizo a propósito. La razón es que ya tienes la información de que el cliente falló, por lo que ya no tiene que ser emitida. De hecho, este no es un buen cambio en cuanto a mantener semver arriba: / Lo siento.
Me gustaría hacer una pequeña encuesta para ver lo que piensan otras personas. Ping @ NodeRedis / contribuyentes @dirkbonhomme
Sí: envíe el error al oyente de errores
No: mantenga la solución actual
Solo para ofrecer un caso de uso a favor del primero, connect-redis proporciona una opción logErrors
que se vuelve (no obviamente) mutuamente excluyente con retry_strategy
si los errores no aparecen.
new RedisStore({
logErrors: (err) => console.error, // does nothing
retry_strategy: (options) => {
if (options.error.code === 'ECONNREFUSED' || options.error.code === 'ENOTFOUND') {
return new Error('The server could not be found or refused the connection');
}
return 1000;
}
})
@tj
Creo que la funcionalidad actual está bien siempre que esté en la documentación, que no lo está. Creo que también sería aceptable agregar una opción que aún generaría errores devueltos por la estrategia de reintento.
Ex.:
redis.createClient({
retry_strategy: ...,
retry_strategy_bubble_up: true or false (default to false to keep existing functionality)
});
Pasé el último día tratando de averiguar por qué no se registraban los errores. Ahora que el registro está en la devolución de llamada retry_strategy, todo está como quiero en mi aplicación.
En lugar de lanzar el error, estoy emitiendo manualmente el evento de error que podría ser detectado por el controlador de errores:
retry_strategy: function(options) {
logger.debug('Retry redis connection: ', options.attempt);
// 5 mins
if (options.total_retry_time > 1000 * 60 * 5) {
// End reconnecting after a specific timeout and flush all commands with a individual error
return logger.error('Redis: maximum retry time exhausted');
}
if (options.attempt > 5) {
// End reconnecting with built in error
logger.error('Redis: maximum connection retry reached');
return client.emit('error', 'maximum retry');
}
return 1000 * 2;
},
Burbujear ! (o algo mas)
El emisor de error personalizado como @alannesta escribió es desordenado, retry_strategy
es uno de los parámetros del constructor, no debería acceder al objeto que está fuera de la función.
NodeRedis
ya tenía un sistema de eventos, ¡solo utilícelo!
Como se tomó end
, y significa "conexión cerrada", podemos agregar un nuevo evento (llamémoslo "apagado" por ahora) que indique "hicimos todo lo posible, esta conexión está muerta" , de ahora en adelante, no haremos nada al respecto, será mejor que hagas algunos trabajos de limpieza ".
Realmente necesito este cambio.
¿Pasó algo con este problema?
¿Hay alguna razón por la que esto no sea fijo o simplemente prioritario? ¿Cuál es el beneficio de no emitir el evento? No hay una forma obvia de cerrar un servicio sin más conexión de redis en funcionamiento cuando se usa retry_strategy
y ese debería ser un caso de uso bastante básico. Sin embargo, la mejor solución probablemente sería un evento separado como sugirió @AaronJan .
Lancé v3.0.0, que ahora muestra cualquier error retry_strategy
devuelto hasta el detector de eventos error
.
Comentario más útil
Sí: envíe el error al oyente de errores