Skip to content

Commit cc95b3d

Browse files
committed
refactor(socket): Add maintenance mode support and dynamic timeout handling
- Introduced `#inMaintenance` property and setter to track maintenance mode state in `RedisSocket`. - Added `#maintenanceTimeout` and `setMaintenanceTimeout` method to dynamically adjust socket timeouts during maintenance. - Enhanced timeout error handling to differentiate between regular timeouts (`SocketTimeoutError`) and maintenance-specific timeouts (`SocketTimeoutDuringMaintananceError`).
1 parent d803ec1 commit cc95b3d

File tree

1 file changed

+26
-3
lines changed

1 file changed

+26
-3
lines changed

packages/client/lib/client/socket.ts

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { EventEmitter, once } from 'node:events';
22
import net from 'node:net';
33
import tls from 'node:tls';
4-
import { ConnectionTimeoutError, ClientClosedError, SocketClosedUnexpectedlyError, ReconnectStrategyError, SocketTimeoutError } from '../errors';
4+
import { ConnectionTimeoutError, ClientClosedError, SocketClosedUnexpectedlyError, ReconnectStrategyError, SocketTimeoutError, SocketTimeoutDuringMaintananceError } from '../errors';
55
import { setTimeout } from 'node:timers/promises';
66
import { RedisArgument } from '../RESP/types';
77

@@ -57,6 +57,8 @@ export default class RedisSocket extends EventEmitter {
5757
readonly #socketFactory;
5858
readonly #socketTimeout;
5959

60+
#maintenanceTimeout: number | undefined;
61+
6062
#socket?: net.Socket | tls.TLSSocket;
6163

6264
#isOpen = false;
@@ -79,7 +81,13 @@ export default class RedisSocket extends EventEmitter {
7981
return this.#socketEpoch;
8082
}
8183

82-
constructor(initiator: RedisSocketInitiator, options?: RedisSocketOptions) {
84+
#inMaintenance = false;
85+
86+
set inMaintenance(value: boolean) {
87+
this.#inMaintenance = value;
88+
}
89+
90+
constructor(options?: RedisSocketOptions) {
8391
super();
8492

8593
this.#connectTimeout = options?.connectTimeout ?? 5000;
@@ -234,6 +242,18 @@ export default class RedisSocket extends EventEmitter {
234242
} while (this.#isOpen && !this.#isReady);
235243
}
236244

245+
setMaintenanceTimeout(ms?: number) {
246+
if (this.#maintenanceTimeout === ms) return;
247+
248+
this.#maintenanceTimeout = ms;
249+
250+
if(ms !== undefined) {
251+
this.#socket?.setTimeout(ms);
252+
} else {
253+
this.#socket?.setTimeout(this.#socketTimeout ?? 0);
254+
}
255+
}
256+
237257
async #createSocket(): Promise<net.Socket | tls.TLSSocket> {
238258
const socket = this.#socketFactory.create();
239259

@@ -256,7 +276,10 @@ export default class RedisSocket extends EventEmitter {
256276

257277
if (this.#socketTimeout) {
258278
socket.once('timeout', () => {
259-
socket.destroy(new SocketTimeoutError(this.#socketTimeout!));
279+
const error = this.#inMaintenance
280+
? new SocketTimeoutDuringMaintananceError(this.#socketTimeout!)
281+
: new SocketTimeoutError(this.#socketTimeout!)
282+
socket.destroy(error);
260283
});
261284
socket.setTimeout(this.#socketTimeout);
262285
}

0 commit comments

Comments
 (0)