Skip to content

Commit ac808ea

Browse files
committedDec 8, 2021
fix #1766 - allow .quit() in PubSub mode
1 parent e112568 commit ac808ea

File tree

3 files changed

+21
-2
lines changed

3 files changed

+21
-2
lines changed
 

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

+8-1
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,19 @@
11
import * as LinkedList from 'yallist';
22
import { AbortError } from '../errors';
33
import { RedisCommandArguments, RedisCommandRawReply } from '../commands';
4+
45
// We need to use 'require', because it's not possible with Typescript to import
56
// classes that are exported as 'module.exports = class`, without esModuleInterop
67
// set to true.
78
const RedisParser = require('redis-parser');
9+
810
export interface QueueCommandOptions {
911
asap?: boolean;
1012
chainId?: symbol;
1113
signal?: AbortSignal;
14+
ignorePubSubMode?: boolean;
1215
}
16+
1317
interface CommandWaitingToBeSent extends CommandWaitingForReply {
1418
args: RedisCommandArguments;
1519
chainId?: symbol;
@@ -18,16 +22,19 @@ interface CommandWaitingToBeSent extends CommandWaitingForReply {
1822
listener(): void;
1923
};
2024
}
25+
2126
interface CommandWaitingForReply {
2227
resolve(reply?: unknown): void;
2328
reject(err: Error): void;
2429
channelsCounter?: number;
2530
bufferMode?: boolean;
2631
}
32+
2733
export enum PubSubSubscribeCommands {
2834
SUBSCRIBE = 'SUBSCRIBE',
2935
PSUBSCRIBE = 'PSUBSCRIBE'
3036
}
37+
3138
export enum PubSubUnsubscribeCommands {
3239
UNSUBSCRIBE = 'UNSUBSCRIBE',
3340
PUNSUBSCRIBE = 'PUNSUBSCRIBE'
@@ -135,7 +142,7 @@ export default class RedisCommandsQueue {
135142
}
136143

137144
addCommand<T = RedisCommandRawReply>(args: RedisCommandArguments, options?: QueueCommandOptions, bufferMode?: boolean): Promise<T> {
138-
if (this.#pubSubState) {
145+
if (this.#pubSubState && !options?.ignorePubSubMode) {
139146
return Promise.reject(new Error('Cannot send commands in PubSub mode'));
140147
} else if (this.#maxLength && this.#waitingToBeSent.length + this.#waitingForReply.length >= this.#maxLength) {
141148
return Promise.reject(new Error('The queue is full'));

‎packages/client/lib/client/index.spec.ts

+10
Original file line numberDiff line numberDiff line change
@@ -668,6 +668,16 @@ describe('Client', () => {
668668
await subscriber.disconnect();
669669
}
670670
}, GLOBAL.SERVERS.OPEN);
671+
672+
testUtils.testWithClient('should be able to quit in PubSub mode', async client => {
673+
await client.subscribe('channel', () => {
674+
// noop
675+
});
676+
677+
await assert.doesNotReject(client.quit());
678+
679+
assert.equal(client.isOpen, false);
680+
}, GLOBAL.SERVERS.OPEN);
671681
});
672682

673683
testUtils.testWithClient('ConnectionTimeoutError', async client => {

‎packages/client/lib/client/index.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -487,7 +487,9 @@ export default class RedisClient<M extends RedisModules, S extends RedisScripts>
487487

488488
QUIT(): Promise<void> {
489489
return this.#socket.quit(() => {
490-
const quitPromise = this.#queue.addCommand(['QUIT']);
490+
const quitPromise = this.#queue.addCommand(['QUIT'], {
491+
ignorePubSubMode: true
492+
});
491493
this.#tick();
492494
return Promise.all([
493495
quitPromise,

0 commit comments

Comments
 (0)
Please sign in to comment.