Wir hatten eine retry_strategy implementiert, die nach einer bestimmten Anzahl von Wiederholungen einen Fehler ausgibt. Dies würde dann zum on('error')-Handler von Redis blasen, um protokolliert zu werden und die Anwendung zu beenden. Beim Aktualisieren unserer Redis-Bibliothek von 2.4.2
auf 2.6.2
wir festgestellt, dass dieses Verhalten nicht mehr dasselbe ist.
Repro-Fall:
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.
}
Das ist eigentlich etwas, das mit Absicht gemacht wurde. Der Grund ist, dass Sie bereits über die Information verfügen, dass der Client ausgefallen ist, sodass diese nicht mehr ausgegeben werden muss. Dies ist in der Tat keine gute Abwechslung, wenn es darum geht, den Semver aufrechtzuerhalten :/ Das tut mir leid.
Ich hätte gerne eine kleine Umfrage, um zu sehen, was andere Leute denken. Ping @NodeRedis/contributors @dirkbonhomme
Ja: Blasen Sie den Fehler in den Fehler-Listener
Nein: Behalten Sie die aktuelle Lösung bei
Nur um einen Anwendungsfall zugunsten des ersteren anzubieten, bietet connect-redis eine Option logErrors
die sich (nicht offensichtlich) mit retry_strategy
gegenseitig ausschließt, wenn keine Fehler auftreten.
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
Ich denke, die aktuelle Funktionalität ist in Ordnung, solange sie in der Dokumentation enthalten ist, was nicht der Fall ist. Ich denke, es wäre auch akzeptabel, eine Option hinzuzufügen, die immer noch Fehler aus der Wiederholungsstrategie aufbläst.
Ex.:
redis.createClient({
retry_strategy: ...,
retry_strategy_bubble_up: true or false (default to false to keep existing functionality)
});
Habe gerade den letzten Tag damit verbracht, herauszufinden, warum Fehler nicht protokolliert wurden. Jetzt, da die Protokollierung im retry_strategy-Callback erfolgt, ist in meiner Anwendung alles so, wie ich es haben möchte.
Anstatt den Fehler auszulösen, gebe ich manuell das Fehlerereignis aus, das vom Fehlerhandler abgefangen werden könnte:
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;
},
Blase auf! (oder etwas anderes)
Benutzerdefinierter Fehler-Emitter, wie @alannesta schrieb, ist chaotisch, retry_strategy
ist einer der Parameter des Konstruktors, er sollte nicht auf Objekte außerhalb der Funktion zugreifen.
NodeRedis
bereits ein Event-System, benutze es einfach!
Da end
ist und dies bedeutet, dass die Verbindung geschlossen ist, können wir ein neues Ereignis hinzufügen (nennen wir es vorerst einfach "Herunterfahren"), das anzeigt, dass "wir haben alles getan, was wir konnten, diese Verbindung ist tot , von nun an tun wir nichts dagegen, du machst besser ein paar Aufräumarbeiten".
Ich brauche diese Veränderung wirklich.
Ist bei diesem Problem etwas passiert?
Gibt es einen Grund, warum dies nicht behoben ist oder nur Priorität hat? Welchen Vorteil hat es , das Ereignis retry_strategy
und das sollte ein ziemlich grundlegender Anwendungsfall sein. Die beste Lösung wäre jedoch wahrscheinlich ein separates Event, wie @AaronJan vorgeschlagen hat.
Ich habe v3.0.0 veröffentlicht, das jetzt alle zurückgegebenen retry_strategy
Fehler bis zum error
Ereignis-Listener führt.
Hilfreichster Kommentar
Ja: Blasen Sie den Fehler in den Fehler-Listener