Skip to content

Commit

Permalink
feat(cluster): support retrying MOVED with a delay
Browse files Browse the repository at this point in the history
Add delay to MOVED response. In case a MOVED response is recieved from the cluster use a delayed queue to retry commands
  • Loading branch information
ohad-israeli authored and luin committed Mar 14, 2021
1 parent acafa0e commit e9b3e57
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 1 deletion.
8 changes: 8 additions & 0 deletions lib/cluster/ClusterOptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*
Expand Down Expand Up @@ -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",
Expand Down
10 changes: 9 additions & 1 deletion lib/cluster/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down

0 comments on commit e9b3e57

Please sign in to comment.