You've already forked node-redis
mirror of
https://github.com/redis/node-redis.git
synced 2025-08-06 02:15:48 +03:00
deprecate QUIT
and disconnect
, implement close
and destroy
This commit is contained in:
@@ -41,9 +41,7 @@ To override just a specific option, use the following functions:
|
|||||||
|
|
||||||
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.
|
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.
|
||||||
|
|
||||||
Rather than using `client.quit()`, your code should use `client.close()` or `client.disconnect()`.
|
`client.QUIT/quit()` is replaced by `client.close()`. and, to avoid confusion, `client.disconnect()` has been renamed to `client.destroy()`.
|
||||||
|
|
||||||
TODO difference between `close` and `disconnect`...
|
|
||||||
|
|
||||||
## Scan Iterators
|
## Scan Iterators
|
||||||
|
|
||||||
@@ -62,7 +60,7 @@ const client = createClient(),
|
|||||||
// use `client` for the new API
|
// use `client` for the new API
|
||||||
await client.set('key', 'value');
|
await client.set('key', 'value');
|
||||||
|
|
||||||
// use `legacyClient` for the "legacy" callback API
|
// use `legacyClient` for the "legacy" API
|
||||||
legacyClient.set('key', 'value', (err, reply) => {
|
legacyClient.set('key', 'value', (err, reply) => {
|
||||||
// ...
|
// ...
|
||||||
});
|
});
|
||||||
|
@@ -316,4 +316,11 @@ export default class RedisCommandsQueue {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
isEmpty() {
|
||||||
|
return (
|
||||||
|
this._waitingToBeSent.length === 0 &&
|
||||||
|
this._waitingForReply.length === 0
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -657,16 +657,6 @@ export default class RedisClient<
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
QUIT(): Promise<string> {
|
|
||||||
return this._socket.quit(async () => {
|
|
||||||
const quitPromise = this._queue.addCommand<string>(['QUIT']);
|
|
||||||
this._tick();
|
|
||||||
return quitPromise;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
quit = this.QUIT;
|
|
||||||
|
|
||||||
private _tick(force = false): void {
|
private _tick(force = false): void {
|
||||||
if (this._socket.writableNeedDrain || (!force && !this._socket.isReady)) {
|
if (this._socket.writableNeedDrain || (!force && !this._socket.isReady)) {
|
||||||
return;
|
return;
|
||||||
@@ -674,12 +664,12 @@ export default class RedisClient<
|
|||||||
|
|
||||||
this._socket.cork();
|
this._socket.cork();
|
||||||
|
|
||||||
while (!this._socket.writableNeedDrain) {
|
do {
|
||||||
const args = this._queue.getCommandToSend();
|
const args = this._queue.getCommandToSend();
|
||||||
if (args === undefined) break;
|
if (args === undefined) break;
|
||||||
|
|
||||||
this._socket.writeCommand(args);
|
this._socket.writeCommand(args);
|
||||||
}
|
} while (!this._socket.writableNeedDrain);
|
||||||
}
|
}
|
||||||
|
|
||||||
private _addMultiCommands(
|
private _addMultiCommands(
|
||||||
@@ -782,9 +772,57 @@ export default class RedisClient<
|
|||||||
} while (cursor !== 0);
|
} while (cursor !== 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated use .close instead
|
||||||
|
*/
|
||||||
|
QUIT(): Promise<string> {
|
||||||
|
return this._socket.quit(async () => {
|
||||||
|
const quitPromise = this._queue.addCommand<string>(['QUIT']);
|
||||||
|
this._tick();
|
||||||
|
return quitPromise;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
quit = this.QUIT;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated use .destroy instead
|
||||||
|
*/
|
||||||
disconnect() {
|
disconnect() {
|
||||||
|
return Promise.resolve(this.destroy());
|
||||||
|
}
|
||||||
|
|
||||||
|
private _resolveClose?: () => unknown;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Close the client. Wait for pending replies.
|
||||||
|
*/
|
||||||
|
close() {
|
||||||
|
return new Promise<void>(resolve => {
|
||||||
|
this._socket.close();
|
||||||
|
|
||||||
|
if (this._queue.isEmpty()) {
|
||||||
|
this._socket.destroySocket();
|
||||||
|
return resolve();
|
||||||
|
}
|
||||||
|
|
||||||
|
const maybeClose = () => {
|
||||||
|
if (!this._queue.isEmpty()) return;
|
||||||
|
|
||||||
|
this._socket.off('data', maybeClose);
|
||||||
|
this._socket.destroySocket();
|
||||||
|
resolve();
|
||||||
|
};
|
||||||
|
this._socket.on('data', maybeClose);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destroy the client. Rejects all commands immediately.
|
||||||
|
*/
|
||||||
|
destroy() {
|
||||||
this._queue.flushAll(new DisconnectsClientError());
|
this._queue.flushAll(new DisconnectsClientError());
|
||||||
this._socket.disconnect();
|
this._socket.destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
ref() {
|
ref() {
|
||||||
|
@@ -19,7 +19,7 @@ export interface RedisSocketCommonOptions {
|
|||||||
*/
|
*/
|
||||||
keepAlive?: number | false;
|
keepAlive?: number | false;
|
||||||
/**
|
/**
|
||||||
* When the socket closes unexpectedly (without calling `.quit()`/`.disconnect()`), the client uses `reconnectStrategy` to decide what to do. The following values are supported:
|
* When the socket closes unexpectedly (without calling `.close()`/`.destroy()`), the client uses `reconnectStrategy` to decide what to do. The following values are supported:
|
||||||
* 1. `false` -> do not reconnect, close the client and flush the command queue.
|
* 1. `false` -> do not reconnect, close the client and flush the command queue.
|
||||||
* 2. `number` -> wait for `X` milliseconds before reconnecting.
|
* 2. `number` -> wait for `X` milliseconds before reconnecting.
|
||||||
* 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.
|
* 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,16 +250,35 @@ export default class RedisSocket extends EventEmitter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
disconnect(): void {
|
async quit<T>(fn: () => Promise<T>): Promise<T> {
|
||||||
if (!this.#isOpen) {
|
if (!this.#isOpen) {
|
||||||
throw new ClientClosedError();
|
throw new ClientClosedError();
|
||||||
}
|
}
|
||||||
|
|
||||||
this.#isOpen = false;
|
this.#isOpen = false;
|
||||||
this.#disconnect();
|
const reply = await fn();
|
||||||
|
this.destroySocket();
|
||||||
|
return reply;
|
||||||
}
|
}
|
||||||
|
|
||||||
#disconnect(): void {
|
close() {
|
||||||
|
if (!this.#isOpen) {
|
||||||
|
throw new ClientClosedError();
|
||||||
|
}
|
||||||
|
|
||||||
|
this.#isOpen = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
destroy() {
|
||||||
|
if (!this.#isOpen) {
|
||||||
|
throw new ClientClosedError();
|
||||||
|
}
|
||||||
|
|
||||||
|
this.#isOpen = false;
|
||||||
|
this.destroySocket();
|
||||||
|
}
|
||||||
|
|
||||||
|
destroySocket() {
|
||||||
this.#isReady = false;
|
this.#isReady = false;
|
||||||
|
|
||||||
if (this.#socket) {
|
if (this.#socket) {
|
||||||
@@ -270,17 +289,6 @@ export default class RedisSocket extends EventEmitter {
|
|||||||
this.emit('end');
|
this.emit('end');
|
||||||
}
|
}
|
||||||
|
|
||||||
async quit<T>(fn: () => Promise<T>): Promise<T> {
|
|
||||||
if (!this.#isOpen) {
|
|
||||||
throw new ClientClosedError();
|
|
||||||
}
|
|
||||||
|
|
||||||
this.#isOpen = false;
|
|
||||||
const reply = await fn();
|
|
||||||
this.#disconnect();
|
|
||||||
return reply;
|
|
||||||
}
|
|
||||||
|
|
||||||
#isCorked = false;
|
#isCorked = false;
|
||||||
|
|
||||||
cork(): void {
|
cork(): void {
|
||||||
|
Reference in New Issue
Block a user