一定量の再試行後にエラーを発行するretry_strategyを実装しました。 これにより、Redisのon( 'error')ハンドラーにバブルしてログに記録し、アプリケーションを終了します。 redisライブラリを2.4.2
から2.6.2
に更新すると、この動作が同じではなくなっていることがわかりました。
再現ケース:
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.
}
これは実際には意図的に行われたものです。 その理由は、クライアントが失敗したという情報をすでに持っているので、それをもう発行する必要がないからです。 これは確かにsemverを維持することについての良い変更ではありません:/それについては申し訳ありません。
他の人が何を考えているかを確認するために、ちょっとした世論調査をしたいと思います。 @ NodeRedis / Contributors @ dirkbonhommeにpingを実行します
はい:エラーをエラーリスナーにバブルアップします
いいえ:現在のソリューションを維持します
前者を支持するユースケースを提供するために、 connect-redisはlogErrors
オプションを提供します。これは、エラーが発生しない場合、(明らかに) retry_strategy
と相互に排他的になります。
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
ドキュメントに記載されている限り、現在の機能は問題ないと思いますが、そうではありません。 再試行戦略から返されるエラーをバブルアップするオプションを追加することも許容できると思います。
元。:
redis.createClient({
retry_strategy: ...,
retry_strategy_bubble_up: true or false (default to false to keep existing functionality)
});
エラーがログに記録されなかった理由を理解するために、最後の日を過ごしました。 ロギングがretry_strategyコールバックにあるので、すべてがアプリケーションで必要なとおりになります。
エラーをスローする代わりに、エラーハンドラーによってキャッチされる可能性のあるエラーイベントを手動で発行しています。
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;
},
わきたつ ! (または、他の何か)
@alannestaが書いたようなカスタムエラーエミッターは厄介です。 retry_strategy
はコンストラクターのパラメーターの1つであり、関数の外部にあるオブジェクトにアクセスするべきではありません。
NodeRedis
すでにイベントシステムがあります。それを使用してください。
end
が取得され、「接続が閉じられました」という意味なので、「できる限りのことをしたので、この接続は切断されました」という新しいイベントを追加できます(今は「シャットダウン」と呼びましょう)。 、これからは何もしません。クリーンアップ作業を行う方がよいでしょう。」
私は本当にこの変更が必要です。
この問題で何かが起こりましたか?
これが固定されていない、または単に優先されている理由はありますか? イベントを発行しないことの利点は何ですか? retry_strategy
を使用しているときに、redis接続が機能していない状態でサービスをシャットダウンする明確な方法はありません。これは、かなり基本的なユースケースであるはずです。 ただし、 @ AaronJanが提案したように、最善の解決策はおそらく別のイベントです。
v3.0.0をリリースしました。これにより、返されたretry_strategy
エラーがerror
イベントリスナーまでバブルされます。
最も参考になるコメント
はい:エラーをエラーリスナーにバブルアップします