From e9b3e57abce8108a414c0f0c0fae8adc1c7c604f Mon Sep 17 00:00:00 2001 From: ohad-israeli Date: Mon, 7 Dec 2020 20:31:23 +0200 Subject: [PATCH] feat(cluster): support retrying MOVED with a delay Add delay to MOVED response. In case a MOVED response is recieved from the cluster use a delayed queue to retry commands --- lib/cluster/ClusterOptions.ts | 8 ++++++++ lib/cluster/index.ts | 10 +++++++++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/lib/cluster/ClusterOptions.ts b/lib/cluster/ClusterOptions.ts index 6b76b2bc0..9565c1526 100644 --- a/lib/cluster/ClusterOptions.ts +++ b/lib/cluster/ClusterOptions.ts @@ -38,6 +38,13 @@ export interface IClusterOptions { reason?: Error ) => number | void | null; + /** + * See "Quick Start" section. + * + * @default (times) => Math.min(50 + times * 2, 2000) + */ + retryDelayOnMoved?: (times: number, reason?: Error) => number | null; + /** * See Redis class. * @@ -180,6 +187,7 @@ export interface IClusterOptions { export const DEFAULT_CLUSTER_OPTIONS: IClusterOptions = { clusterRetryStrategy: (times) => Math.min(100 + times * 2, 2000), + retryDelayOnMoved: (times) => Math.min(50 + times * 2, 2000), enableOfflineQueue: true, enableReadyCheck: true, scaleReads: "master", diff --git a/lib/cluster/index.ts b/lib/cluster/index.ts index 06bdd10e7..d8afbc56d 100644 --- a/lib/cluster/index.ts +++ b/lib/cluster/index.ts @@ -746,7 +746,15 @@ class Cluster extends EventEmitter { } const errv = error.message.split(" "); if (errv[0] === "MOVED" || errv[0] === "ASK") { - handlers[errv[0] === "MOVED" ? "moved" : "ask"](errv[1], errv[2]); + this.delayQueue.push( + "moved", + handlers.moved.bind(null, errv[1], errv[2]), + { + timeout: this.options.retryDelayOnMoved( + this.options.maxRedirections + 1 - ttl.value + ), + } + ); } else if (errv[0] === "TRYAGAIN") { this.delayQueue.push("tryagain", handlers.tryagain, { timeout: this.options.retryDelayOnTryAgain,