Skip to content

Commit

Permalink
Fork: feat: Socket timeout (#14)
Browse files Browse the repository at this point in the history
* feat: add support for `socketTimeout` in `Redis` (#1882)

Signed-off-by: Aleksandr Zinin <[email protected]>

* fix: remove console.log

Signed-off-by: Aleksandr Zinin <[email protected]>

---------

Signed-off-by: Aleksandr Zinin <[email protected]>
Co-authored-by: Leibale Eidelman <[email protected]>
  • Loading branch information
pinkiesky and leibale authored Oct 30, 2024
1 parent 9505d6b commit c1a245b
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 0 deletions.
21 changes: 21 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,22 @@ 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", () => {
clearTimeout(this.socketTimeoutTimer);
this.socketTimeoutTimer = undefined;
if (this.commandQueue.length === 0) return;
this.setSocketTimeout();
});
}

scanStream(options?: ScanStreamOptions) {

Check warning on line 561 in lib/Redis.ts

View workflow job for this annotation

GitHub Actions / test-redis (22.x)

Member scanStream should be declared before all private instance method definitions

Check warning on line 561 in lib/Redis.ts

View workflow job for this annotation

GitHub Actions / test-valkey (18.x)

Member scanStream should be declared before all private instance method definitions

Check warning on line 561 in lib/Redis.ts

View workflow job for this annotation

GitHub Actions / test-redis (20.x)

Member scanStream should be declared before all private instance method definitions

Check warning on line 561 in lib/Redis.ts

View workflow job for this annotation

GitHub Actions / test-valkey (20.x)

Member scanStream should be declared before all private instance method definitions

Check warning on line 561 in lib/Redis.ts

View workflow job for this annotation

GitHub Actions / test-valkey (22.x)

Member scanStream should be declared before all private instance method definitions

Check warning on line 561 in lib/Redis.ts

View workflow job for this annotation

GitHub Actions / test-redis (18.x)

Member scanStream should be declared before all private instance method definitions
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 c1a245b

Please sign in to comment.