Skip to content

Commit 673ac77

Browse files
authored
feat: add support for socketTimeout in Redis (#1882)
1 parent ec42c82 commit 673ac77

File tree

2 files changed

+31
-0
lines changed

2 files changed

+31
-0
lines changed

lib/Redis.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ class Redis extends Commander implements DataHandledable {
106106
private connectionEpoch = 0;
107107
private retryAttempts = 0;
108108
private manuallyClosing = false;
109+
private socketTimeoutTimer: NodeJS.Timeout | undefined;
109110

110111
// Prepare autopipelines structures
111112
private _autoPipelines = new Map();
@@ -523,6 +524,10 @@ class Redis extends Commander implements DataHandledable {
523524
if (Command.checkFlag("WILL_DISCONNECT", command.name)) {
524525
this.manuallyClosing = true;
525526
}
527+
528+
if (this.options.socketTimeout !== undefined && this.socketTimeoutTimer === undefined) {
529+
this.setSocketTimeout();
530+
}
526531
}
527532

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

545+
private setSocketTimeout() {
546+
this.socketTimeoutTimer = setTimeout(() => {
547+
this.stream.destroy(new Error(`Socket timeout. Expecting data, but didn't receive any in ${this.options.socketTimeout}ms.`));
548+
this.socketTimeoutTimer = undefined;
549+
}, this.options.socketTimeout);
550+
551+
// this handler must run after the "data" handler in "DataHandler"
552+
// so that `this.commandQueue.length` will be updated
553+
this.stream.once("data", () => {
554+
console.log('GOT DATA, CLEARING TIMER');
555+
clearTimeout(this.socketTimeoutTimer);
556+
this.socketTimeoutTimer = undefined;
557+
if (this.commandQueue.length === 0) return;
558+
this.setSocketTimeout();
559+
});
560+
}
561+
540562
scanStream(options?: ScanStreamOptions) {
541563
return this.createScanStream("scan", { options });
542564
}

lib/redis/RedisOptions.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,15 @@ export interface CommonRedisOptions extends CommanderOptions {
1414
* a "Command timed out" error will be thrown.
1515
*/
1616
commandTimeout?: number;
17+
18+
/**
19+
* If the socket does not receive data within a set number of milliseconds:
20+
* 1. the socket is considered "dead" and will be destroyed
21+
* 2. the client will reject any running commands (altought they might have been processed by the server)
22+
* 3. the reconnect strategy will kick in (depending on the configuration)
23+
*/
24+
socketTimeout?: number;
25+
1726
/**
1827
* Enable/disable keep-alive functionality.
1928
* @link https://nodejs.org/api/net.html#socketsetkeepaliveenable-initialdelay

0 commit comments

Comments
 (0)