Skip to content

Commit dcfad0f

Browse files
authored
Merge pull request #69 from Workable/introduce-default-queue-type
Introduce default queue type
2 parents 1da7ff3 + 97effe5 commit dcfad0f

3 files changed

Lines changed: 101 additions & 2 deletions

File tree

test/rabbit.test.ts

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,81 @@ describe('Test rabbit class', function() {
119119
stub.calledWith(handler).should.be.true();
120120
});
121121

122+
it('should create queue with max priority when priority is specified', async function() {
123+
const subscription = sandbox.stub(Queue.prototype, 'subscribe');
124+
rabbit = new Rabbit(this.url);
125+
await rabbit.connected;
126+
const stub = sandbox.stub(rabbit.consumeChannel, 'assertQueue')
127+
.resolves({ queue: this.name, messageCount: 0, consumerCount: 0 });
128+
const priority = 23;
129+
const handler = () => {};
130+
await rabbit.createQueue(this.name, { priority: priority }, handler);
131+
subscription.calledWith(handler).should.be.true();
132+
const [name, options] = stub.firstCall.args;
133+
name.should.equal(this.name);
134+
options!.arguments['x-max-priority'].should.equals(priority);
135+
});
136+
137+
it('should apply queue type when defaultQueueType is provided', async function() {
138+
const subscription = sandbox.stub(Queue.prototype, 'subscribe');
139+
const queueType = 'classic';
140+
rabbit = new Rabbit(this.url, { defaultQueueType: queueType });
141+
await rabbit.connected;
142+
const stub = sandbox.stub(rabbit.consumeChannel, 'assertQueue')
143+
.resolves({ queue: this.name, messageCount: 0, consumerCount: 0 });
144+
const handler = () => {};
145+
await rabbit.createQueue(this.name, {}, handler);
146+
subscription.calledWith(handler).should.be.true();
147+
const [name, options] = stub.firstCall.args;
148+
name.should.equal(this.name);
149+
options!.arguments['x-queue-type'].should.equals(queueType);
150+
});
151+
152+
it('should not set x-queue-type when neither default nor explicit queue type is provided', async function() {
153+
const subscription = sandbox.stub(Queue.prototype, 'subscribe');
154+
rabbit = new Rabbit(this.url);
155+
await rabbit.connected;
156+
const stub = sandbox.stub(rabbit.consumeChannel, 'assertQueue')
157+
.resolves({ queue: this.name, messageCount: 0, consumerCount: 0 });
158+
const handler = () => {};
159+
await rabbit.createQueue(this.name, { }, handler);
160+
subscription.calledWith(handler).should.be.true();
161+
stub.calledOnce.should.be.true();
162+
const [name, options] = stub.firstCall.args;
163+
name.should.equal(this.name);
164+
options!.arguments.should.not.have.property('x-queue-type');
165+
});
166+
167+
it('should use the provided queue type instead of the default', async function() {
168+
const subscription = sandbox.stub(Queue.prototype, 'subscribe');
169+
rabbit = new Rabbit(this.url, { defaultQueueType: 'classic' });
170+
await rabbit.connected;
171+
const stub = sandbox.stub(rabbit.consumeChannel, 'assertQueue')
172+
.resolves({ queue: this.name, messageCount: 0, consumerCount: 0 });
173+
const handler = () => {};
174+
const queueType = 'quorum';
175+
await rabbit.createQueue(this.name, { arguments: { 'x-queue-type': queueType }}, handler);
176+
subscription.calledWith(handler).should.be.true();
177+
const [name, options] = stub.firstCall.args;
178+
name.should.equal(this.name);
179+
options!.arguments['x-queue-type'].should.equals(queueType);
180+
});
181+
182+
it('should ignore priority when creating a quorum queue', async function() {
183+
const subscription = sandbox.stub(Queue.prototype, 'subscribe');
184+
rabbit = new Rabbit(this.url, { defaultQueueType: 'quorum' });
185+
await rabbit.connected;
186+
const stub = sandbox.stub(rabbit.consumeChannel, 'assertQueue')
187+
.resolves({ queue: this.name, messageCount: 0, consumerCount: 0 });
188+
const handler = () => {};
189+
await rabbit.createQueue(this.name, { priority: 23 }, handler);
190+
subscription.calledWith(handler).should.be.true();
191+
stub.calledOnce.should.be.true();
192+
const [name, options] = stub.firstCall.args;
193+
name.should.equal(this.name);
194+
options!.arguments.should.not.have.property('x-max-priority');
195+
});
196+
122197
it('should unsubscribe', async function() {
123198
const stub = sandbox.stub(Queue.prototype, 'unsubscribe');
124199
rabbit = new Rabbit(this.url);

ts/queue.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,11 @@ export default class Queue {
5454
if (priority !== undefined) {
5555
queueOptions.arguments = { ...queueOptions.arguments, 'x-max-priority': priority };
5656
}
57+
if (queueOptions.arguments?.['x-max-priority'] &&
58+
queueOptions.arguments?.['x-queue-type'] === 'quorum') {
59+
logger.warn(`Invalid x-max-priority argument for quorum queue '${this.name}'`);
60+
delete queueOptions.arguments['x-max-priority'];
61+
}
5762
await this.channel.assertQueue(this.name, queueOptions);
5863
}
5964

ts/rabbit.ts

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,26 @@ export default class Rabbit extends EventEmitter {
2525
public prefix: string;
2626
public scheduledPublish: boolean;
2727
public socketOptions;
28+
private defaultQueueType: string | undefined;
2829
public logger: ReturnType<typeof getLogger>;
2930

3031
constructor(
3132
public url: string,
32-
{ prefetch = 1, replyPattern = true, prefix = '', scheduledPublish = false, socketOptions = {} } = {}
33+
{
34+
prefetch = 1,
35+
replyPattern = true,
36+
prefix = '',
37+
scheduledPublish = false,
38+
socketOptions = {},
39+
defaultQueueType = undefined,
40+
}: {
41+
prefetch?: number
42+
replyPattern?: boolean
43+
prefix?: string
44+
scheduledPublish?: boolean
45+
socketOptions?: any
46+
defaultQueueType?: string
47+
} = {}
3348
) {
3449
super();
3550
if (!Rabbit.INSTANCE) {
@@ -42,6 +57,7 @@ export default class Rabbit extends EventEmitter {
4257
this.prefix = prefix;
4358
this.scheduledPublish = scheduledPublish;
4459
this.socketOptions = socketOptions;
60+
this.defaultQueueType = defaultQueueType;
4561
this.reconnect();
4662
}
4763

@@ -101,9 +117,12 @@ export default class Rabbit extends EventEmitter {
101117

102118
async createQueue(
103119
name: string,
104-
options: amqp.Options.AssertQueue & { prefix?: string; prefetch? } = {},
120+
options: amqp.Options.AssertQueue & amqp.Options.Consume & { prefix?: string; prefetch? } = {},
105121
handler?: (msg: any, ack: (error?, reply?) => any) => any
106122
) {
123+
if (this.defaultQueueType && !options.arguments?.['x-queue-type']) {
124+
options.arguments = { ...options.arguments, 'x-queue-type': this.defaultQueueType };
125+
}
107126
options.prefetch = options.prefetch || this.prefetch;
108127
name = this.updateName(name, options.prefix);
109128
await this.connected;

0 commit comments

Comments
 (0)