Skip to content

Commit

Permalink
feat: add support for socketTimeout in Redis (#1882)
Browse files Browse the repository at this point in the history
  • Loading branch information
leibale authored Apr 16, 2024
1 parent ec42c82 commit 673ac77
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 0 deletions.
22 changes: 22 additions & 0 deletions lib/Redis.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ class Redis extends Commander implements DataHandledable {
private connectionEpoch = 0;
private retryAttempts = 0;
private manuallyClosing = false;
private socketTimeoutTimer: NodeJS.Timeout | undefined;

// Prepare autopipelines structures
private _autoPipelines = new Map();
Expand Down Expand Up @@ -523,6 +524,10 @@ class Redis extends Commander implements DataHandledable {
if (Command.checkFlag("WILL_DISCONNECT", command.name)) {
this.manuallyClosing = true;
}

if (this.options.socketTimeout !== undefined && this.socketTimeoutTimer === undefined) {
this.setSocketTimeout();
}
}

if (command.name === "select" && isInt(command.args[0])) {
Expand All @@ -537,6 +542,23 @@ class Redis extends Commander implements DataHandledable {
return command.promise;
}

private setSocketTimeout() {
this.socketTimeoutTimer = setTimeout(() => {
this.stream.destroy(new Error(`Socket timeout. Expecting data, but didn't receive any in ${this.options.socketTimeout}ms.`));
this.socketTimeoutTimer = undefined;
}, this.options.socketTimeout);

// this handler must run after the "data" handler in "DataHandler"
// so that `this.commandQueue.length` will be updated
this.stream.once("data", () => {
console.log('GOT DATA, CLEARING TIMER');
clearTimeout(this.socketTimeoutTimer);
this.socketTimeoutTimer = undefined;
if (this.commandQueue.length === 0) return;
this.setSocketTimeout();
});
}

scanStream(options?: ScanStreamOptions) {
return this.createScanStream("scan", { options });
}
Expand Down
9 changes: 9 additions & 0 deletions lib/redis/RedisOptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,15 @@ export interface CommonRedisOptions extends CommanderOptions {
* a "Command timed out" error will be thrown.
*/
commandTimeout?: number;

/**
* If the socket does not receive data within a set number of milliseconds:
* 1. the socket is considered "dead" and will be destroyed
* 2. the client will reject any running commands (altought they might have been processed by the server)
* 3. the reconnect strategy will kick in (depending on the configuration)
*/
socketTimeout?: number;

/**
* Enable/disable keep-alive functionality.
* @link https://nodejs.org/api/net.html#socketsetkeepaliveenable-initialdelay
Expand Down

0 comments on commit 673ac77

Please sign in to comment.