You've already forked node-redis
mirror of
https://github.com/redis/node-redis.git
synced 2025-08-07 13:22:56 +03:00
fix client.reset
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
import { SinglyLinkedList, DoublyLinkedNode, DoublyLinkedList } from './linked-list';
|
||||
import encodeCommand from '../RESP/encoder';
|
||||
import { Decoder, PUSH_TYPE_MAPPING, RESP_TYPES } from '../RESP/decoder';
|
||||
import { CommandArguments, TypeMapping, ReplyUnion, RespVersions, SimpleStringReply, ReplyWithTypeMapping } from '../RESP/types';
|
||||
import { CommandArguments, TypeMapping, ReplyUnion, RespVersions } from '../RESP/types';
|
||||
import { ChannelListeners, PubSub, PubSubCommand, PubSubListener, PubSubType, PubSubTypeListeners } from './pub-sub';
|
||||
import { AbortError, ErrorReply } from '../errors';
|
||||
import { MonitorCallback } from '.';
|
||||
@@ -154,11 +154,11 @@ export default class RedisCommandsQueue {
|
||||
});
|
||||
}
|
||||
|
||||
#addPubSubCommand(command: PubSubCommand, asap = false) {
|
||||
#addPubSubCommand(command: PubSubCommand, asap = false, chainId?: symbol) {
|
||||
return new Promise<void>((resolve, reject) => {
|
||||
this.#toWrite.add({
|
||||
args: command.args,
|
||||
chainId: undefined,
|
||||
chainId,
|
||||
abort: undefined,
|
||||
resolve() {
|
||||
command.resolve();
|
||||
@@ -237,13 +237,13 @@ export default class RedisCommandsQueue {
|
||||
return this.#addPubSubCommand(command);
|
||||
}
|
||||
|
||||
resubscribe() {
|
||||
resubscribe(chainId?: symbol) {
|
||||
const commands = this.#pubSub.resubscribe();
|
||||
if (!commands.length) return;
|
||||
|
||||
this.#setupPubSubHandler();
|
||||
return Promise.all(
|
||||
commands.map(command => this.#addPubSubCommand(command, true))
|
||||
commands.map(command => this.#addPubSubCommand(command, true, chainId))
|
||||
);
|
||||
}
|
||||
|
||||
@@ -271,11 +271,12 @@ export default class RedisCommandsQueue {
|
||||
return this.#pubSub.getTypeListeners(type);
|
||||
}
|
||||
|
||||
monitor(callback: MonitorCallback, typeMapping: TypeMapping = {}, asap = false) {
|
||||
monitor(callback: MonitorCallback, options?: CommandOptions) {
|
||||
return new Promise<void>((resolve, reject) => {
|
||||
const typeMapping = options?.typeMapping ?? {};
|
||||
this.#toWrite.add({
|
||||
args: ['MONITOR'],
|
||||
chainId: undefined,
|
||||
chainId: options?.chainId,
|
||||
abort: undefined,
|
||||
// using `resolve` instead of using `.then`/`await` to make sure it'll be called before processing the next reply
|
||||
resolve: () => {
|
||||
@@ -295,7 +296,7 @@ export default class RedisCommandsQueue {
|
||||
reject,
|
||||
channelsCounter: undefined,
|
||||
typeMapping
|
||||
}, asap);
|
||||
}, options?.asap);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -306,7 +307,7 @@ export default class RedisCommandsQueue {
|
||||
|
||||
#resetFallbackOnReply?: Decoder['onReply'];
|
||||
|
||||
async reset<T extends TypeMapping>(typeMapping?: T) {
|
||||
async reset<T extends TypeMapping>(chainId: symbol, typeMapping?: T) {
|
||||
return new Promise((resolve, reject) => {
|
||||
// overriding onReply to handle `RESET` while in `MONITOR` or PubSub mode
|
||||
this.#resetFallbackOnReply = this.decoder.onReply;
|
||||
@@ -328,7 +329,7 @@ export default class RedisCommandsQueue {
|
||||
|
||||
this.#toWrite.push({
|
||||
args: ['RESET'],
|
||||
chainId: undefined,
|
||||
chainId,
|
||||
abort: undefined,
|
||||
resolve,
|
||||
reject,
|
||||
|
@@ -732,6 +732,9 @@ describe('Client', () => {
|
||||
skipMe: true
|
||||
})
|
||||
]);
|
||||
|
||||
await once(duplicate, 'ready');
|
||||
|
||||
await Promise.all([
|
||||
waitTillBeenCalled(listener),
|
||||
client.ping()
|
||||
|
@@ -332,24 +332,8 @@ export default class RedisClient<
|
||||
);
|
||||
}
|
||||
|
||||
#handshake(asap = false, promises: Array<Promise<unknown>> = []) {
|
||||
if (this.#selectedDB !== 0) {
|
||||
promises.push(
|
||||
this.#queue.addCommand(
|
||||
['SELECT', this.#selectedDB.toString()],
|
||||
{ asap }
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if (this.#options?.readonly) {
|
||||
promises.push(
|
||||
this.#queue.addCommand(
|
||||
COMMANDS.READONLY.transformArguments(),
|
||||
{ asap }
|
||||
)
|
||||
);
|
||||
}
|
||||
#handshake(selectedDB: number) {
|
||||
const commands = [];
|
||||
|
||||
if (this.#options?.RESP) {
|
||||
const hello: HelloOptions = {};
|
||||
@@ -365,43 +349,45 @@ export default class RedisClient<
|
||||
hello.SETNAME = this.#options.name;
|
||||
}
|
||||
|
||||
promises.push(
|
||||
this.#queue.addCommand(
|
||||
HELLO.transformArguments(this.#options.RESP, hello),
|
||||
{ asap }
|
||||
)
|
||||
commands.push(
|
||||
HELLO.transformArguments(this.#options.RESP, hello)
|
||||
);
|
||||
} else {
|
||||
if (this.#options?.name) {
|
||||
promises.push(
|
||||
this.#queue.addCommand(
|
||||
COMMANDS.CLIENT_SETNAME.transformArguments(this.#options.name),
|
||||
{ asap }
|
||||
)
|
||||
if (this.#options?.username || this.#options?.password) {
|
||||
commands.push(
|
||||
COMMANDS.AUTH.transformArguments({
|
||||
username: this.#options.username,
|
||||
password: this.#options.password ?? ''
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
if (this.#options?.username || this.#options?.password) {
|
||||
promises.push(
|
||||
this.#queue.addCommand(
|
||||
COMMANDS.AUTH.transformArguments({
|
||||
username: this.#options.username,
|
||||
password: this.#options.password ?? ''
|
||||
}),
|
||||
{ asap }
|
||||
)
|
||||
if (this.#options?.name) {
|
||||
commands.push(
|
||||
COMMANDS.CLIENT_SETNAME.transformArguments(this.#options.name)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return promises;
|
||||
if (selectedDB !== 0) {
|
||||
commands.push(['SELECT', this.#selectedDB.toString()]);
|
||||
}
|
||||
|
||||
if (this.#options?.readonly) {
|
||||
commands.push(
|
||||
COMMANDS.READONLY.transformArguments()
|
||||
);
|
||||
}
|
||||
|
||||
return commands;
|
||||
}
|
||||
|
||||
#initiateSocket(): RedisSocket {
|
||||
const socketInitiator = () => {
|
||||
const promises: Array<Promise<unknown>> = [];
|
||||
const promises = [],
|
||||
chainId = Symbol('Socket Initiator');
|
||||
|
||||
const resubscribePromise = this.#queue.resubscribe();
|
||||
const resubscribePromise = this.#queue.resubscribe(chainId);
|
||||
if (resubscribePromise) {
|
||||
promises.push(resubscribePromise);
|
||||
}
|
||||
@@ -410,13 +396,24 @@ export default class RedisClient<
|
||||
promises.push(
|
||||
this.#queue.monitor(
|
||||
this.#monitorCallback,
|
||||
this._commandOptions?.typeMapping,
|
||||
true
|
||||
{
|
||||
typeMapping: this._commandOptions?.typeMapping,
|
||||
chainId,
|
||||
asap: true
|
||||
}
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
this.#handshake(true, promises);
|
||||
const commands = this.#handshake(this.#selectedDB);
|
||||
for (let i = commands.length - 1; i >= 0; --i) {
|
||||
promises.push(
|
||||
this.#queue.addCommand(commands[i], {
|
||||
chainId,
|
||||
asap: true
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
if (promises.length) {
|
||||
this.#write();
|
||||
@@ -885,7 +882,9 @@ export default class RedisClient<
|
||||
}
|
||||
|
||||
async MONITOR(callback: MonitorCallback<TYPE_MAPPING>) {
|
||||
const promise = this._self.#queue.monitor(callback, this._commandOptions?.typeMapping);
|
||||
const promise = this._self.#queue.monitor(callback, {
|
||||
typeMapping: this._commandOptions?.typeMapping
|
||||
});
|
||||
this._self.#scheduleWrite();
|
||||
await promise;
|
||||
this._self.#monitorCallback = callback;
|
||||
@@ -897,10 +896,20 @@ export default class RedisClient<
|
||||
* Reset the client to its default state (i.e. stop PubSub, stop monitoring, select default DB, etc.)
|
||||
*/
|
||||
async reset() {
|
||||
const promises = [this._self.#queue.reset()];
|
||||
this._self.#handshake(false, promises);
|
||||
const chainId = Symbol('Reset Chain'),
|
||||
promises = [this._self.#queue.reset(chainId)],
|
||||
selectedDB = this._self.#options?.database ?? 0;
|
||||
for (const command of this._self.#handshake(selectedDB)) {
|
||||
promises.push(
|
||||
this._self.#queue.addCommand(command, {
|
||||
chainId
|
||||
})
|
||||
);
|
||||
}
|
||||
this._self.#scheduleWrite();
|
||||
await Promise.all(promises);
|
||||
this._self.#selectedDB = selectedDB;
|
||||
this._self.#monitorCallback = undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
|
Reference in New Issue
Block a user