Skip to content

Commit e332613

Browse files
committed
deprecate QUIT and disconnect, implement close and destroy
1 parent f8fa887 commit e332613

File tree

4 files changed

+82
-31
lines changed

4 files changed

+82
-31
lines changed

docs/v4-to-v5.md

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,7 @@ To override just a specific option, use the following functions:
4141

4242
The `QUIT` command has been deprecated in Redis 7.2 and should now also be considered deprecated in Node-Redis. Instead of sending a `QUIT` command to the server, the client can simply close the network connection.
4343

44-
Rather than using `client.quit()`, your code should use `client.close()` or `client.disconnect()`.
45-
46-
TODO difference between `close` and `disconnect`...
44+
`client.QUIT/quit()` is replaced by `client.close()`. and, to avoid confusion, `client.disconnect()` has been renamed to `client.destroy()`.
4745

4846
## Scan Iterators
4947

@@ -62,7 +60,7 @@ const client = createClient(),
6260
// use `client` for the new API
6361
await client.set('key', 'value');
6462

65-
// use `legacyClient` for the "legacy" callback API
63+
// use `legacyClient` for the "legacy" API
6664
legacyClient.set('key', 'value', (err, reply) => {
6765
// ...
6866
});

packages/client/lib/client/commands-queue.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -316,4 +316,11 @@ export default class RedisCommandsQueue {
316316
);
317317
}
318318
}
319+
320+
isEmpty() {
321+
return (
322+
this._waitingToBeSent.length === 0 &&
323+
this._waitingForReply.length === 0
324+
);
325+
}
319326
}

packages/client/lib/client/index.ts

Lines changed: 51 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -657,29 +657,19 @@ export default class RedisClient<
657657
);
658658
}
659659

660-
QUIT(): Promise<string> {
661-
return this._socket.quit(async () => {
662-
const quitPromise = this._queue.addCommand<string>(['QUIT']);
663-
this._tick();
664-
return quitPromise;
665-
});
666-
}
667-
668-
quit = this.QUIT;
669-
670660
private _tick(force = false): void {
671661
if (this._socket.writableNeedDrain || (!force && !this._socket.isReady)) {
672662
return;
673663
}
674664

675665
this._socket.cork();
676666

677-
while (!this._socket.writableNeedDrain) {
667+
do {
678668
const args = this._queue.getCommandToSend();
679669
if (args === undefined) break;
680670

681671
this._socket.writeCommand(args);
682-
}
672+
} while (!this._socket.writableNeedDrain);
683673
}
684674

685675
private _addMultiCommands(
@@ -782,9 +772,57 @@ export default class RedisClient<
782772
} while (cursor !== 0);
783773
}
784774

775+
/**
776+
* @deprecated use .close instead
777+
*/
778+
QUIT(): Promise<string> {
779+
return this._socket.quit(async () => {
780+
const quitPromise = this._queue.addCommand<string>(['QUIT']);
781+
this._tick();
782+
return quitPromise;
783+
});
784+
}
785+
786+
quit = this.QUIT;
787+
788+
/**
789+
* @deprecated use .destroy instead
790+
*/
785791
disconnect() {
792+
return Promise.resolve(this.destroy());
793+
}
794+
795+
private _resolveClose?: () => unknown;
796+
797+
/**
798+
* Close the client. Wait for pending replies.
799+
*/
800+
close() {
801+
return new Promise<void>(resolve => {
802+
this._socket.close();
803+
804+
if (this._queue.isEmpty()) {
805+
this._socket.destroySocket();
806+
return resolve();
807+
}
808+
809+
const maybeClose = () => {
810+
if (!this._queue.isEmpty()) return;
811+
812+
this._socket.off('data', maybeClose);
813+
this._socket.destroySocket();
814+
resolve();
815+
};
816+
this._socket.on('data', maybeClose);
817+
});
818+
}
819+
820+
/**
821+
* Destroy the client. Rejects all commands immediately.
822+
*/
823+
destroy() {
786824
this._queue.flushAll(new DisconnectsClientError());
787-
this._socket.disconnect();
825+
this._socket.destroy();
788826
}
789827

790828
ref() {

packages/client/lib/client/socket.ts

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ export interface RedisSocketCommonOptions {
1919
*/
2020
keepAlive?: number | false;
2121
/**
22-
* When the socket closes unexpectedly (without calling `.quit()`/`.disconnect()`), the client uses `reconnectStrategy` to decide what to do. The following values are supported:
22+
* When the socket closes unexpectedly (without calling `.close()`/`.destroy()`), the client uses `reconnectStrategy` to decide what to do. The following values are supported:
2323
* 1. `false` -> do not reconnect, close the client and flush the command queue.
2424
* 2. `number` -> wait for `X` milliseconds before reconnecting.
2525
* 3. `(retries: number, cause: Error) => false | number | Error` -> `number` is the same as configuring a `number` directly, `Error` is the same as `false`, but with a custom error.
@@ -250,35 +250,43 @@ export default class RedisSocket extends EventEmitter {
250250
}
251251
}
252252

253-
disconnect(): void {
253+
async quit<T>(fn: () => Promise<T>): Promise<T> {
254254
if (!this.#isOpen) {
255255
throw new ClientClosedError();
256256
}
257257

258258
this.#isOpen = false;
259-
this.#disconnect();
259+
const reply = await fn();
260+
this.destroySocket();
261+
return reply;
260262
}
261263

262-
#disconnect(): void {
263-
this.#isReady = false;
264-
265-
if (this.#socket) {
266-
this.#socket.destroy();
267-
this.#socket = undefined;
264+
close() {
265+
if (!this.#isOpen) {
266+
throw new ClientClosedError();
268267
}
269268

270-
this.emit('end');
269+
this.#isOpen = false;
271270
}
272271

273-
async quit<T>(fn: () => Promise<T>): Promise<T> {
272+
destroy() {
274273
if (!this.#isOpen) {
275274
throw new ClientClosedError();
276275
}
277276

278277
this.#isOpen = false;
279-
const reply = await fn();
280-
this.#disconnect();
281-
return reply;
278+
this.destroySocket();
279+
}
280+
281+
destroySocket() {
282+
this.#isReady = false;
283+
284+
if (this.#socket) {
285+
this.#socket.destroy();
286+
this.#socket = undefined;
287+
}
288+
289+
this.emit('end');
282290
}
283291

284292
#isCorked = false;

0 commit comments

Comments
 (0)