@autofleet/rabbit 3.2.24-beta.2 → 3.2.24-beta.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +10 -15
- package/dist/index.js +65 -80
- package/dist/lib/consts.d.ts +0 -4
- package/dist/lib/consts.js +1 -6
- package/dist/lib/types.d.ts +0 -5
- package/package.json +2 -2
- package/src/index.ts +82 -104
- package/src/lib/consts.ts +0 -5
- package/src/lib/types.ts +0 -6
package/dist/index.d.ts
CHANGED
|
@@ -3,8 +3,7 @@ import { EventEmitter } from 'events';
|
|
|
3
3
|
import { AmqpConnectionManager, ChannelWrapper, CreateChannelOpts } from 'amqp-connection-manager';
|
|
4
4
|
import { ConfirmChannel, ConsumeMessage, Options, Replies } from 'amqplib';
|
|
5
5
|
import { RedisConfig } from './lib/redis';
|
|
6
|
-
import {
|
|
7
|
-
import { CallbackFunction, ConsumeMessageOrNull, ConsumeOptions, CustomMessageHeaders, QueuesCache, RedisLockType, ExchangesCache, QueueSetupPromisesDictionary, AssertExchangePromisesDictionary, ConnectionData } from './lib/types';
|
|
6
|
+
import { CallbackFunction, ConsumeMessageOrNull, ConsumeOptions, CustomMessageHeaders, QueuesCache, RedisLockType, ExchangesCache, QueueSetupPromisesDictionary, AssertExchangePromisesDictionary } from './lib/types';
|
|
8
7
|
export interface IAfRabbitMq {
|
|
9
8
|
ack: any;
|
|
10
9
|
nack: any;
|
|
@@ -38,12 +37,10 @@ type newChannelOpts = {
|
|
|
38
37
|
name?: string;
|
|
39
38
|
onClose?: null | ((args: any | null) => void);
|
|
40
39
|
options?: CreateChannelOpts | undefined;
|
|
41
|
-
connectionPurpose?: ConnectionPurpose;
|
|
42
40
|
};
|
|
43
41
|
type assertChannelOpts = {
|
|
44
42
|
channelName?: string;
|
|
45
43
|
force?: boolean;
|
|
46
|
-
connectionPurpose?: ConnectionPurpose;
|
|
47
44
|
};
|
|
48
45
|
declare class RabbitMq implements IAfRabbitMq {
|
|
49
46
|
static parseMsg(msg: any): any;
|
|
@@ -63,11 +60,9 @@ declare class RabbitMq implements IAfRabbitMq {
|
|
|
63
60
|
channel: ChannelWrapper | null;
|
|
64
61
|
publishChannelSetupPromise: Promise<ChannelWrapper> | null;
|
|
65
62
|
blockReconnect: boolean | null | undefined;
|
|
66
|
-
|
|
67
|
-
[ConnectionPurpose.Consume]: ConnectionData;
|
|
68
|
-
[ConnectionPurpose.Publish]: ConnectionData;
|
|
69
|
-
};
|
|
63
|
+
connection: AmqpConnectionManager | null | undefined;
|
|
70
64
|
em: EventEmitter;
|
|
65
|
+
creatingConnection: boolean;
|
|
71
66
|
exchanges: ExchangesCache;
|
|
72
67
|
queues: QueuesCache;
|
|
73
68
|
queueSetupPromises: QueueSetupPromisesDictionary;
|
|
@@ -82,16 +77,16 @@ declare class RabbitMq implements IAfRabbitMq {
|
|
|
82
77
|
private shouldConsumeMessageByTimestamp;
|
|
83
78
|
ack: (channel: ConfirmChannel, msg: ConsumeMessageOrNull, shouldUpdateRedisTimestamp?: boolean, releaseLock?: null) => (userMsg: ConsumeMessage) => Promise<any>;
|
|
84
79
|
nack: (channel: ConfirmChannel, queue: string, options: any, deadQueueOptions: Options.AssertQueue, msg: ConsumeMessageOrNull, releaseLock: any) => (userMsg: ConsumeMessageOrNull, { skipRetry, }?: NackOptions) => Promise<any>;
|
|
85
|
-
getConnection(
|
|
86
|
-
getNewChannel({ name, onClose, options
|
|
87
|
-
assertChannel({ force
|
|
80
|
+
getConnection(): Promise<AmqpConnectionManager>;
|
|
81
|
+
getNewChannel({ name, onClose, options }?: newChannelOpts): Promise<ChannelWrapper>;
|
|
82
|
+
assertChannel({ force }?: assertChannelOpts): Promise<ChannelWrapper>;
|
|
88
83
|
assertExchange(exchangeName: string, options?: any): Promise<any>;
|
|
89
|
-
getQueueLength(queue: string
|
|
84
|
+
getQueueLength(queue: string): Promise<Replies.AssertQueue>;
|
|
90
85
|
private deleteQueue;
|
|
91
|
-
bindQueue(queue: string, exchange: string
|
|
92
|
-
setupQueue(queueName: string,
|
|
86
|
+
bindQueue(queue: string, exchange: string): Promise<void>;
|
|
87
|
+
setupQueue(queueName: string, options?: Options.AssertQueue): Promise<Replies.AssertQueue>;
|
|
93
88
|
static shouldUseQuorum(queueName: string): boolean;
|
|
94
|
-
assertQueue(queueName: string,
|
|
89
|
+
assertQueue(queueName: string, options?: Options.AssertQueue): Promise<any>;
|
|
95
90
|
private saveConsumer;
|
|
96
91
|
consume(queue: string, callback: CallbackFunction, options?: ConsumeOptions): Promise<any>;
|
|
97
92
|
private lockRedisIfNeeded;
|
package/dist/index.js
CHANGED
|
@@ -119,10 +119,8 @@ class RabbitMq {
|
|
|
119
119
|
this.em = new events_1.EventEmitter();
|
|
120
120
|
this.channel = null;
|
|
121
121
|
this.publishChannelSetupPromise = null;
|
|
122
|
-
this.
|
|
123
|
-
|
|
124
|
-
[consts_1.ConnectionPurpose.Publish]: { connection: null, creatingConnection: false },
|
|
125
|
-
};
|
|
122
|
+
this.connection = null;
|
|
123
|
+
this.creatingConnection = false;
|
|
126
124
|
this.exchanges = {};
|
|
127
125
|
this.queues = {};
|
|
128
126
|
this.queueSetupPromises = {};
|
|
@@ -144,31 +142,30 @@ class RabbitMq {
|
|
|
144
142
|
});
|
|
145
143
|
}
|
|
146
144
|
}
|
|
147
|
-
async getConnection(
|
|
145
|
+
async getConnection() {
|
|
148
146
|
return new Promise(async (resolve, reject) => {
|
|
149
|
-
const { connection, creatingConnection } = this.connectionsMap[connectionPurpose];
|
|
150
147
|
if (this.blockReconnect) {
|
|
151
148
|
debug('rabbit: block reconnect');
|
|
152
149
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
153
150
|
// @ts-ignore
|
|
154
151
|
return resolve();
|
|
155
152
|
}
|
|
156
|
-
if (connection !== null) {
|
|
157
|
-
if (this.options?.disableReconnect || connection?.isConnected()) {
|
|
153
|
+
if (this.connection !== null) {
|
|
154
|
+
if (this.options?.disableReconnect || this.connection?.isConnected()) {
|
|
158
155
|
debug('rabbit: connection - is connected');
|
|
159
156
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
160
157
|
// @ts-ignore
|
|
161
|
-
return resolve(connection);
|
|
158
|
+
return resolve(this.connection);
|
|
162
159
|
}
|
|
163
160
|
debug('rabbit: connection - reconnecting');
|
|
164
161
|
}
|
|
165
|
-
if (creatingConnection) {
|
|
162
|
+
if (this.creatingConnection) {
|
|
166
163
|
debug('rabbit: creating connection emi');
|
|
167
164
|
this.em.once(consts_1.CONNECTION_CREATED_CONST, resolve);
|
|
168
165
|
this.em.once(consts_1.CONNECTION_FAILED_CONST, reject);
|
|
169
166
|
return;
|
|
170
167
|
}
|
|
171
|
-
this.
|
|
168
|
+
this.creatingConnection = true;
|
|
172
169
|
let isResolved = false;
|
|
173
170
|
// It is import to use it as a function and not as a variable
|
|
174
171
|
// because of k8s changes the env variables
|
|
@@ -181,12 +178,11 @@ class RabbitMq {
|
|
|
181
178
|
return [`amqp://${userName}:${password}@${host}?heartbeat=${HEARTBEAT}`];
|
|
182
179
|
};
|
|
183
180
|
const defaultUrls = findServers();
|
|
184
|
-
const
|
|
181
|
+
const connection = await (0, amqp_connection_manager_1.connect)(defaultUrls, {
|
|
185
182
|
findServers,
|
|
186
183
|
});
|
|
187
|
-
this.
|
|
188
|
-
|
|
189
|
-
newConnection.on('error', (err) => {
|
|
184
|
+
this.connection = connection;
|
|
185
|
+
this.connection.on('error', (err) => {
|
|
190
186
|
logger_1.default.error('rabbit: connection error', { err });
|
|
191
187
|
if (!isResolved) {
|
|
192
188
|
isResolved = true;
|
|
@@ -194,7 +190,7 @@ class RabbitMq {
|
|
|
194
190
|
this.em.emit(consts_1.CONNECTION_FAILED_CONST, err);
|
|
195
191
|
}
|
|
196
192
|
});
|
|
197
|
-
|
|
193
|
+
this.connection.on('connectFailed', (err) => {
|
|
198
194
|
this.consumersTags = [];
|
|
199
195
|
logger_1.default.error('rabbit: connection connectFailed', { err });
|
|
200
196
|
if (!isResolved) {
|
|
@@ -203,7 +199,8 @@ class RabbitMq {
|
|
|
203
199
|
this.em.emit(consts_1.CONNECTION_FAILED_CONST, err);
|
|
204
200
|
}
|
|
205
201
|
});
|
|
206
|
-
|
|
202
|
+
this.connection.on('disconnect', ({ err }) => {
|
|
203
|
+
// this.channel = null;
|
|
207
204
|
this.consumersTags = [];
|
|
208
205
|
debug('rabbit: connection closed');
|
|
209
206
|
if (this.options?.disableReconnect) {
|
|
@@ -214,26 +211,24 @@ class RabbitMq {
|
|
|
214
211
|
logger_1.default.error(`${this.RECONNECT_MSG}${err && ` - ${err}`}`);
|
|
215
212
|
}
|
|
216
213
|
});
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
this.
|
|
214
|
+
this.connection.once('connect', async () => {
|
|
215
|
+
debug('rabbit: connection established');
|
|
216
|
+
this.creatingConnection = false;
|
|
217
|
+
this.em.emit(consts_1.CONNECTION_CREATED_CONST, connection);
|
|
220
218
|
isResolved = true;
|
|
221
|
-
resolve(
|
|
219
|
+
resolve(connection);
|
|
222
220
|
});
|
|
223
221
|
});
|
|
224
222
|
}
|
|
225
|
-
async getNewChannel({ name = (0, utils_1.rand)().toString(), onClose = null, options = {}
|
|
223
|
+
async getNewChannel({ name = (0, utils_1.rand)().toString(), onClose = null, options = {} } = {}) {
|
|
226
224
|
let connection;
|
|
227
225
|
try {
|
|
228
|
-
connection = await this.getConnection(
|
|
226
|
+
connection = await this.getConnection();
|
|
229
227
|
}
|
|
230
228
|
catch (e) {
|
|
231
229
|
logger_1.default.error(`rabbit: error on get connection for new channel ${name} `, { e });
|
|
232
230
|
throw e;
|
|
233
231
|
}
|
|
234
|
-
if (!connection) {
|
|
235
|
-
throw new Error(`rabbit: couldnt get connection for new channel ${name}`);
|
|
236
|
-
}
|
|
237
232
|
const channel = connection.createChannel({ ...options });
|
|
238
233
|
(0, events_1.once)(channel, 'close').then((args) => {
|
|
239
234
|
logger_1.default.error(`rabbit: channel ${name} closed`);
|
|
@@ -249,16 +244,14 @@ class RabbitMq {
|
|
|
249
244
|
throw err;
|
|
250
245
|
}
|
|
251
246
|
}
|
|
252
|
-
async assertChannel({ force = false
|
|
253
|
-
debug('rabbit: start assert channel', { connectionPurpose, publishPromise: this.publishChannelSetupPromise, channel: this.channel });
|
|
247
|
+
async assertChannel({ force = false } = {}) {
|
|
254
248
|
if (!this.publishChannelSetupPromise) {
|
|
255
249
|
this.publishChannelSetupPromise = new Promise(async (resolve, reject) => {
|
|
256
250
|
if (this.channel && !force) {
|
|
257
251
|
return resolve(this.channel);
|
|
258
252
|
}
|
|
259
253
|
try {
|
|
260
|
-
const channel = await this.getNewChannel({
|
|
261
|
-
debug('rabbit: new channel got', { connectionPurpose, channel: this.channel });
|
|
254
|
+
const channel = await this.getNewChannel({});
|
|
262
255
|
channel.on('error', (err) => {
|
|
263
256
|
logger_1.default.error('rabbit: channel error', { err });
|
|
264
257
|
});
|
|
@@ -272,8 +265,8 @@ class RabbitMq {
|
|
|
272
265
|
}
|
|
273
266
|
return this.publishChannelSetupPromise;
|
|
274
267
|
}
|
|
275
|
-
async assertExchange(exchangeName, options
|
|
276
|
-
const channel = await this.assertChannel(
|
|
268
|
+
async assertExchange(exchangeName, options) {
|
|
269
|
+
const channel = await this.assertChannel();
|
|
277
270
|
if (this.exchanges[exchangeName]) {
|
|
278
271
|
delete this.assertExchangePromises[exchangeName];
|
|
279
272
|
return this.exchanges[exchangeName];
|
|
@@ -285,30 +278,29 @@ class RabbitMq {
|
|
|
285
278
|
this.exchanges[exchangeName] = await this.assertExchangePromises[exchangeName];
|
|
286
279
|
return this.exchanges[exchangeName];
|
|
287
280
|
}
|
|
288
|
-
async getQueueLength(queue
|
|
281
|
+
async getQueueLength(queue) {
|
|
289
282
|
RabbitMq.validateName('queue', queue);
|
|
290
|
-
const { connection } = this.connectionsMap[connectionPurpose];
|
|
291
283
|
const { channel } = this;
|
|
292
284
|
if (!channel) {
|
|
293
285
|
throw new Error('channel is not defined');
|
|
294
286
|
}
|
|
295
|
-
debug('rabbit: getting queue length', { queue, connected: connection?.isConnected() });
|
|
287
|
+
debug('rabbit: getting queue length', { queue, connected: this.connection?.isConnected() });
|
|
296
288
|
return channel?.checkQueue(queue);
|
|
297
289
|
}
|
|
298
|
-
async deleteQueue(queue
|
|
290
|
+
async deleteQueue(queue) {
|
|
299
291
|
RabbitMq.validateName('queue', queue);
|
|
300
|
-
const channel = await this.assertChannel(
|
|
292
|
+
const channel = await this.assertChannel();
|
|
301
293
|
logger_1.default.info('rabbit: deleting queue', { queue });
|
|
302
294
|
const deleteQueueRes = await channel.deleteQueue(queue);
|
|
303
295
|
debug('queue deleted', deleteQueueRes);
|
|
304
296
|
return deleteQueueRes;
|
|
305
297
|
}
|
|
306
|
-
async bindQueue(queue, exchange
|
|
307
|
-
const channel = await this.assertChannel(
|
|
298
|
+
async bindQueue(queue, exchange) {
|
|
299
|
+
const channel = await this.assertChannel();
|
|
308
300
|
await channel.addSetup((setupChannel) => setupChannel.bindQueue(queue, exchange, ''));
|
|
309
301
|
return channel.bindQueue(queue, exchange, '');
|
|
310
302
|
}
|
|
311
|
-
async setupQueue(queueName,
|
|
303
|
+
async setupQueue(queueName, options) {
|
|
312
304
|
let queue;
|
|
313
305
|
const shouldUseQuorum = RabbitMq.shouldUseQuorum(queueName);
|
|
314
306
|
const localeOptions = {
|
|
@@ -321,7 +313,7 @@ class RabbitMq {
|
|
|
321
313
|
},
|
|
322
314
|
};
|
|
323
315
|
try {
|
|
324
|
-
const channel = await this.assertChannel(
|
|
316
|
+
const channel = await this.assertChannel();
|
|
325
317
|
debug('assertQueue->channel.addSetup', { queueName });
|
|
326
318
|
await channel.addSetup((setupChannel) => setupChannel.assertQueue(queueName, localeOptions));
|
|
327
319
|
debug('assertQueue->channel.assertQueue', { queueName });
|
|
@@ -331,8 +323,8 @@ class RabbitMq {
|
|
|
331
323
|
logger_1.default.error('rabbit: assertQueue error', { queueName, options, error: e });
|
|
332
324
|
if (!this.options?.dontRetryAssert) {
|
|
333
325
|
debug('retrying assertQueue', { queueName });
|
|
334
|
-
const channel = await this.assertChannel({ force: true
|
|
335
|
-
await this.deleteQueue(queueName
|
|
326
|
+
const channel = await this.assertChannel({ force: true });
|
|
327
|
+
await this.deleteQueue(queueName);
|
|
336
328
|
debug('retrying assertQueue->channel.addSetup', { queueName });
|
|
337
329
|
await channel.addSetup((setupChannel) => setupChannel.assertQueue(queueName, localeOptions));
|
|
338
330
|
debug('retrying assertQueue->channel.assertQueue', { queueName });
|
|
@@ -356,8 +348,7 @@ class RabbitMq {
|
|
|
356
348
|
}
|
|
357
349
|
return false;
|
|
358
350
|
}
|
|
359
|
-
async assertQueue(queueName,
|
|
360
|
-
debug('rabbit: start assert queue', { connectionPurpose, queueName });
|
|
351
|
+
async assertQueue(queueName, options) {
|
|
361
352
|
RabbitMq.validateName('queue', queueName);
|
|
362
353
|
if (this.queues[queueName]) {
|
|
363
354
|
delete this.queueSetupPromises[queueName];
|
|
@@ -366,8 +357,7 @@ class RabbitMq {
|
|
|
366
357
|
if (this.queueSetupPromises[queueName]) {
|
|
367
358
|
return this.queueSetupPromises[queueName];
|
|
368
359
|
}
|
|
369
|
-
this.queueSetupPromises[queueName] = this.setupQueue(queueName,
|
|
370
|
-
debug('rabbit: done assert queue', { connectionPurpose, queueName });
|
|
360
|
+
this.queueSetupPromises[queueName] = this.setupQueue(queueName, options);
|
|
371
361
|
return this.queueSetupPromises[queueName];
|
|
372
362
|
}
|
|
373
363
|
saveConsumer(queue, callback, options) {
|
|
@@ -410,9 +400,9 @@ class RabbitMq {
|
|
|
410
400
|
}
|
|
411
401
|
logger_1.default.info(`rabbit: Consuming with lock from queue ${queue} with lockTimeout: ${lockTimeout}ms`);
|
|
412
402
|
}
|
|
413
|
-
const channel = await this.getNewChannel({
|
|
403
|
+
const channel = await this.getNewChannel({});
|
|
414
404
|
return channel.addSetup(async (confirmChannel) => {
|
|
415
|
-
const q = await this.assertQueue(queue,
|
|
405
|
+
const q = await this.assertQueue(queue, optionsWithDefaults);
|
|
416
406
|
await confirmChannel.prefetch(limit, false);
|
|
417
407
|
const { consumerTag } = await confirmChannel.consume(queue, async (msg) => {
|
|
418
408
|
if (!msg) {
|
|
@@ -494,7 +484,7 @@ class RabbitMq {
|
|
|
494
484
|
RabbitMq.validateName('queue', queue);
|
|
495
485
|
const { limit, deadMessageTtl } = optionsWithDefaults;
|
|
496
486
|
await this.saveConsumer(queue, callback, options);
|
|
497
|
-
const channel = await this.getNewChannel({ name: `consume
|
|
487
|
+
const channel = await this.getNewChannel({ name: `consume-exchange-${exchange}-queue-${queue}` });
|
|
498
488
|
return channel.addSetup(async (c) => {
|
|
499
489
|
const assertExchange = await (0, utils_1.assertExchangeFanout)(c, exchange);
|
|
500
490
|
await c.assertQueue(queue);
|
|
@@ -509,14 +499,14 @@ class RabbitMq {
|
|
|
509
499
|
async publish(exchange, content, customHeaders) {
|
|
510
500
|
return (0, utils_1.wrapSetImmediate)(async () => {
|
|
511
501
|
RabbitMq.validateName('exchange', exchange);
|
|
512
|
-
const channel = await this.assertChannel(
|
|
513
|
-
await this.assertExchange(exchange
|
|
502
|
+
const channel = await this.assertChannel();
|
|
503
|
+
await this.assertExchange(exchange);
|
|
514
504
|
await channel.publish(exchange, '', Buffer.from(JSON.stringify(content)), RabbitMq.getPublishOptions(customHeaders));
|
|
515
505
|
});
|
|
516
506
|
}
|
|
517
507
|
async sendToQueue(queue, content, options, customHeaders) {
|
|
518
508
|
try {
|
|
519
|
-
await this.assertChannel(
|
|
509
|
+
await this.assertChannel();
|
|
520
510
|
}
|
|
521
511
|
catch (e) {
|
|
522
512
|
logger_1.default.error(`rabbit sendToQueue: failed to send assert channel when sending to queue ${queue}`, { e });
|
|
@@ -524,7 +514,7 @@ class RabbitMq {
|
|
|
524
514
|
}
|
|
525
515
|
try {
|
|
526
516
|
RabbitMq.validateName('queue', queue);
|
|
527
|
-
await this.assertQueue(queue,
|
|
517
|
+
await this.assertQueue(queue, options);
|
|
528
518
|
}
|
|
529
519
|
catch (e) {
|
|
530
520
|
logger_1.default.error(`rabbit sendToQueue: failed to assert queue ${queue}`, { e });
|
|
@@ -536,36 +526,31 @@ class RabbitMq {
|
|
|
536
526
|
return res;
|
|
537
527
|
}
|
|
538
528
|
catch (e) {
|
|
539
|
-
|
|
529
|
+
const isConnected = await this.isConnected();
|
|
530
|
+
logger_1.default.error(`rabbit sendToQueue: failed to send to queue ${queue}, isConnected: ${isConnected}`, { e });
|
|
540
531
|
throw e;
|
|
541
532
|
}
|
|
542
533
|
}
|
|
543
534
|
async isConnected() {
|
|
544
|
-
const
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
return false;
|
|
564
|
-
}
|
|
565
|
-
logger_1.default.info('rabbit: isConnected - true');
|
|
566
|
-
return true;
|
|
567
|
-
}));
|
|
568
|
-
return isEachConnectionConnected.every((isConnected) => isConnected === true);
|
|
535
|
+
const connection = await this.getConnection();
|
|
536
|
+
const isConnected = connection.isConnected();
|
|
537
|
+
if (!isConnected) {
|
|
538
|
+
logger_1.default.error('rabbit: isConnected - false');
|
|
539
|
+
return false;
|
|
540
|
+
}
|
|
541
|
+
const channel = await this.assertChannel();
|
|
542
|
+
try {
|
|
543
|
+
await Promise.all([
|
|
544
|
+
channel.waitForConnect(),
|
|
545
|
+
...this.consumers.map((c) => channel.checkQueue(c.queue)),
|
|
546
|
+
]);
|
|
547
|
+
}
|
|
548
|
+
catch (e) {
|
|
549
|
+
logger_1.default.error('rabbit: isConnected - false');
|
|
550
|
+
return false;
|
|
551
|
+
}
|
|
552
|
+
logger_1.default.info('rabbit: isConnected - true');
|
|
553
|
+
return true;
|
|
569
554
|
}
|
|
570
555
|
async gracefulShutdown(signal) {
|
|
571
556
|
const tagsNumber = this.consumersTags.length;
|
package/dist/lib/consts.d.ts
CHANGED
package/dist/lib/consts.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.DEFAULT_OPTIONS = exports.CONNECTION_FAILED_CONST = exports.CONNECTION_CREATED_CONST = exports.DEFAULT_USE_CONSUME_WITH_LOCK = exports.USER_OBJECT = exports.AUTOMATION_ID_HEADER = exports.USER_TRACING_HEADER = exports.TRACING_HEADER = exports.RETRY_HEADER = exports.DEFAULT_LOCK_TIMEOUT = exports.DEFAULT_DEAD_TTL_TWO_DAYS = void 0;
|
|
4
4
|
exports.DEFAULT_DEAD_TTL_TWO_DAYS = 60000 * 60 * 12;
|
|
5
5
|
exports.DEFAULT_LOCK_TIMEOUT = 1000 * 5;
|
|
6
6
|
exports.RETRY_HEADER = 'x-retry-count';
|
|
@@ -20,8 +20,3 @@ exports.DEFAULT_OPTIONS = {
|
|
|
20
20
|
auditContext: null,
|
|
21
21
|
enableRabbitTrace: false,
|
|
22
22
|
};
|
|
23
|
-
var ConnectionPurpose;
|
|
24
|
-
(function (ConnectionPurpose) {
|
|
25
|
-
ConnectionPurpose["Consume"] = "consume";
|
|
26
|
-
ConnectionPurpose["Publish"] = "publish";
|
|
27
|
-
})(ConnectionPurpose = exports.ConnectionPurpose || (exports.ConnectionPurpose = {}));
|
package/dist/lib/types.d.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { AmqpConnectionManager } from 'amqp-connection-manager';
|
|
2
1
|
import { ConsumeMessage, Options, Replies } from 'amqplib';
|
|
3
2
|
export interface ExchangesCache {
|
|
4
3
|
[key: string]: any;
|
|
@@ -42,7 +41,3 @@ export type AfConsumer = {
|
|
|
42
41
|
options: ConsumeOptions | undefined;
|
|
43
42
|
};
|
|
44
43
|
export declare const CONSUMER_DEFAULT_OPTIONS: Options.Consume;
|
|
45
|
-
export type ConnectionData = {
|
|
46
|
-
connection: AmqpConnectionManager | null;
|
|
47
|
-
creatingConnection: boolean;
|
|
48
|
-
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@autofleet/rabbit",
|
|
3
|
-
"version": "3.2.24-beta.
|
|
3
|
+
"version": "3.2.24-beta.5",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"engines": {
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
"dev": "nodemon"
|
|
19
19
|
},
|
|
20
20
|
"dependencies": {
|
|
21
|
-
"@autofleet/zehut": "^3.
|
|
21
|
+
"@autofleet/zehut": "^3.1.2-beta.16",
|
|
22
22
|
"amqp-connection-manager": "4.1.9",
|
|
23
23
|
"amqplib": "0.10.3",
|
|
24
24
|
"bluebird": "^3.7.2",
|
package/src/index.ts
CHANGED
|
@@ -22,7 +22,6 @@ import {
|
|
|
22
22
|
AUTOMATION_ID_HEADER,
|
|
23
23
|
CONNECTION_CREATED_CONST,
|
|
24
24
|
CONNECTION_FAILED_CONST,
|
|
25
|
-
ConnectionPurpose,
|
|
26
25
|
DEFAULT_LOCK_TIMEOUT,
|
|
27
26
|
DEFAULT_OPTIONS,
|
|
28
27
|
RETRY_HEADER,
|
|
@@ -41,13 +40,13 @@ import {
|
|
|
41
40
|
CONSUMER_DEFAULT_OPTIONS,
|
|
42
41
|
QueueSetupPromisesDictionary,
|
|
43
42
|
AssertExchangePromisesDictionary,
|
|
44
|
-
ConnectionData,
|
|
45
43
|
} from './lib/types';
|
|
46
44
|
|
|
47
45
|
// const debug = nodeDebug('af-rabbitmq')
|
|
48
46
|
const debug = logger.debug.bind(logger);
|
|
49
47
|
|
|
50
48
|
const PUBLISH_TIMEOUT = 1000 * 10;
|
|
49
|
+
|
|
51
50
|
export interface IAfRabbitMq {
|
|
52
51
|
ack: any;
|
|
53
52
|
nack: any;
|
|
@@ -87,13 +86,11 @@ type newChannelOpts = {
|
|
|
87
86
|
name?: string;
|
|
88
87
|
onClose?: null | ((args: any | null) => void);
|
|
89
88
|
options?: CreateChannelOpts | undefined;
|
|
90
|
-
connectionPurpose?: ConnectionPurpose,
|
|
91
89
|
};
|
|
92
90
|
|
|
93
91
|
type assertChannelOpts = {
|
|
94
92
|
channelName?: string;
|
|
95
93
|
force?: boolean;
|
|
96
|
-
connectionPurpose?: ConnectionPurpose;
|
|
97
94
|
}
|
|
98
95
|
|
|
99
96
|
type AfConsumer = {
|
|
@@ -105,7 +102,7 @@ type AfConsumer = {
|
|
|
105
102
|
const HEARTBEAT = '60';
|
|
106
103
|
|
|
107
104
|
class RabbitMq implements IAfRabbitMq {
|
|
108
|
-
static parseMsg(msg: any): any {
|
|
105
|
+
static parseMsg(msg: any) : any {
|
|
109
106
|
let { content } = msg;
|
|
110
107
|
content = content.toString();
|
|
111
108
|
|
|
@@ -150,15 +147,14 @@ class RabbitMq implements IAfRabbitMq {
|
|
|
150
147
|
|
|
151
148
|
publishChannelSetupPromise: Promise<ChannelWrapper> | null;
|
|
152
149
|
|
|
153
|
-
blockReconnect: boolean | null | undefined
|
|
150
|
+
blockReconnect: boolean | null | undefined
|
|
154
151
|
|
|
155
|
-
|
|
156
|
-
[ConnectionPurpose.Consume]: ConnectionData;
|
|
157
|
-
[ConnectionPurpose.Publish]: ConnectionData;
|
|
158
|
-
};
|
|
152
|
+
connection: AmqpConnectionManager | null | undefined
|
|
159
153
|
|
|
160
154
|
em: EventEmitter;
|
|
161
155
|
|
|
156
|
+
creatingConnection: boolean;
|
|
157
|
+
|
|
162
158
|
exchanges: ExchangesCache;
|
|
163
159
|
|
|
164
160
|
queues: QueuesCache;
|
|
@@ -182,10 +178,8 @@ class RabbitMq implements IAfRabbitMq {
|
|
|
182
178
|
this.em = new EventEmitter();
|
|
183
179
|
this.channel = null;
|
|
184
180
|
this.publishChannelSetupPromise = null;
|
|
185
|
-
this.
|
|
186
|
-
|
|
187
|
-
[ConnectionPurpose.Publish]: { connection: null, creatingConnection: false },
|
|
188
|
-
};
|
|
181
|
+
this.connection = null;
|
|
182
|
+
this.creatingConnection = false;
|
|
189
183
|
this.exchanges = {};
|
|
190
184
|
this.queues = {};
|
|
191
185
|
this.queueSetupPromises = {};
|
|
@@ -222,7 +216,7 @@ class RabbitMq implements IAfRabbitMq {
|
|
|
222
216
|
return false;
|
|
223
217
|
}
|
|
224
218
|
|
|
225
|
-
public ack = (channel: ConfirmChannel, msg: ConsumeMessageOrNull, shouldUpdateRedisTimestamp = false, releaseLock = null) => async (userMsg: ConsumeMessage): Promise<any> => {
|
|
219
|
+
public ack = (channel: ConfirmChannel, msg: ConsumeMessageOrNull, shouldUpdateRedisTimestamp = false, releaseLock = null) => async (userMsg: ConsumeMessage) : Promise<any> => {
|
|
226
220
|
if (msg) {
|
|
227
221
|
debug('rabbit acking message', { deliveryTag: msg.fields.deliveryTag });
|
|
228
222
|
await channel.ack(msg);
|
|
@@ -248,8 +242,8 @@ class RabbitMq implements IAfRabbitMq {
|
|
|
248
242
|
userMsg: ConsumeMessageOrNull,
|
|
249
243
|
{
|
|
250
244
|
skipRetry = false,
|
|
251
|
-
}: NackOptions = {},
|
|
252
|
-
): Promise<any> => {
|
|
245
|
+
}: NackOptions = { },
|
|
246
|
+
) : Promise<any> => {
|
|
253
247
|
await this.unlockRedisIfNeeded(releaseLock);
|
|
254
248
|
if (channel && msg) {
|
|
255
249
|
if (
|
|
@@ -283,31 +277,30 @@ class RabbitMq implements IAfRabbitMq {
|
|
|
283
277
|
}
|
|
284
278
|
}
|
|
285
279
|
|
|
286
|
-
async getConnection(
|
|
287
|
-
return new Promise<AmqpConnectionManager
|
|
288
|
-
const { connection, creatingConnection } = this.connectionsMap[connectionPurpose];
|
|
280
|
+
async getConnection() {
|
|
281
|
+
return new Promise<AmqpConnectionManager>(async (resolve, reject) => {
|
|
289
282
|
if (this.blockReconnect) {
|
|
290
283
|
debug('rabbit: block reconnect');
|
|
291
284
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
292
285
|
// @ts-ignore
|
|
293
286
|
return resolve();
|
|
294
287
|
}
|
|
295
|
-
if (connection !== null) {
|
|
296
|
-
if (this.options?.disableReconnect || connection?.isConnected()) {
|
|
288
|
+
if (this.connection !== null) {
|
|
289
|
+
if (this.options?.disableReconnect || this.connection?.isConnected()) {
|
|
297
290
|
debug('rabbit: connection - is connected');
|
|
298
291
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
299
292
|
// @ts-ignore
|
|
300
|
-
return resolve(connection);
|
|
293
|
+
return resolve(this.connection);
|
|
301
294
|
}
|
|
302
295
|
debug('rabbit: connection - reconnecting');
|
|
303
296
|
}
|
|
304
|
-
if (creatingConnection) {
|
|
297
|
+
if (this.creatingConnection) {
|
|
305
298
|
debug('rabbit: creating connection emi');
|
|
306
299
|
this.em.once(CONNECTION_CREATED_CONST, resolve);
|
|
307
300
|
this.em.once(CONNECTION_FAILED_CONST, reject);
|
|
308
301
|
return;
|
|
309
302
|
}
|
|
310
|
-
this.
|
|
303
|
+
this.creatingConnection = true;
|
|
311
304
|
let isResolved = false;
|
|
312
305
|
|
|
313
306
|
// It is import to use it as a function and not as a variable
|
|
@@ -324,14 +317,12 @@ class RabbitMq implements IAfRabbitMq {
|
|
|
324
317
|
};
|
|
325
318
|
|
|
326
319
|
const defaultUrls = findServers();
|
|
327
|
-
const
|
|
320
|
+
const connection: AmqpConnectionManager = await connect(defaultUrls, {
|
|
328
321
|
findServers,
|
|
329
322
|
});
|
|
330
323
|
|
|
331
|
-
this.
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
newConnection.on('error', (err) => {
|
|
324
|
+
this.connection = connection;
|
|
325
|
+
this.connection.on('error', (err) => {
|
|
335
326
|
logger.error('rabbit: connection error', { err });
|
|
336
327
|
if (!isResolved) {
|
|
337
328
|
isResolved = true;
|
|
@@ -340,7 +331,7 @@ class RabbitMq implements IAfRabbitMq {
|
|
|
340
331
|
}
|
|
341
332
|
});
|
|
342
333
|
|
|
343
|
-
|
|
334
|
+
this.connection.on('connectFailed', (err) => {
|
|
344
335
|
this.consumersTags = [];
|
|
345
336
|
logger.error('rabbit: connection connectFailed', { err });
|
|
346
337
|
if (!isResolved) {
|
|
@@ -350,7 +341,8 @@ class RabbitMq implements IAfRabbitMq {
|
|
|
350
341
|
}
|
|
351
342
|
});
|
|
352
343
|
|
|
353
|
-
|
|
344
|
+
this.connection.on('disconnect', ({ err }) => {
|
|
345
|
+
// this.channel = null;
|
|
354
346
|
this.consumersTags = [];
|
|
355
347
|
debug('rabbit: connection closed');
|
|
356
348
|
if (this.options?.disableReconnect) {
|
|
@@ -360,28 +352,25 @@ class RabbitMq implements IAfRabbitMq {
|
|
|
360
352
|
logger.error(`${this.RECONNECT_MSG}${err && ` - ${err}`}`);
|
|
361
353
|
}
|
|
362
354
|
});
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
355
|
+
|
|
356
|
+
this.connection.once('connect', async () => {
|
|
357
|
+
debug('rabbit: connection established');
|
|
358
|
+
this.creatingConnection = false;
|
|
359
|
+
this.em.emit(CONNECTION_CREATED_CONST, connection);
|
|
366
360
|
isResolved = true;
|
|
367
|
-
resolve(
|
|
361
|
+
resolve(connection);
|
|
368
362
|
});
|
|
369
363
|
});
|
|
370
364
|
}
|
|
371
365
|
|
|
372
|
-
async getNewChannel({
|
|
373
|
-
|
|
374
|
-
}: newChannelOpts): Promise<ChannelWrapper> {
|
|
375
|
-
let connection!: AmqpConnectionManager | undefined | null;
|
|
366
|
+
async getNewChannel({ name = rand().toString(), onClose = null, options = {} }: newChannelOpts = {}) {
|
|
367
|
+
let connection!: AmqpConnectionManager;
|
|
376
368
|
try {
|
|
377
|
-
connection = await this.getConnection(
|
|
369
|
+
connection = await this.getConnection();
|
|
378
370
|
} catch (e) {
|
|
379
371
|
logger.error(`rabbit: error on get connection for new channel ${name} `, { e });
|
|
380
372
|
throw e;
|
|
381
373
|
}
|
|
382
|
-
if (!connection) {
|
|
383
|
-
throw new Error(`rabbit: couldnt get connection for new channel ${name}`);
|
|
384
|
-
}
|
|
385
374
|
const channel = connection.createChannel({ ...options });
|
|
386
375
|
once(channel, 'close').then((args) => {
|
|
387
376
|
logger.error(`rabbit: channel ${name} closed`);
|
|
@@ -397,8 +386,7 @@ class RabbitMq implements IAfRabbitMq {
|
|
|
397
386
|
}
|
|
398
387
|
}
|
|
399
388
|
|
|
400
|
-
async assertChannel({ force = false
|
|
401
|
-
debug('rabbit: start assert channel', { connectionPurpose, publishPromise: this.publishChannelSetupPromise, channel: this.channel });
|
|
389
|
+
async assertChannel({ force = false } : assertChannelOpts = {}): Promise<ChannelWrapper> {
|
|
402
390
|
if (!this.publishChannelSetupPromise) {
|
|
403
391
|
this.publishChannelSetupPromise = new Promise<ChannelWrapper>(async (resolve, reject) => {
|
|
404
392
|
if (this.channel && !force) {
|
|
@@ -406,8 +394,7 @@ class RabbitMq implements IAfRabbitMq {
|
|
|
406
394
|
}
|
|
407
395
|
|
|
408
396
|
try {
|
|
409
|
-
const channel = await this.getNewChannel({
|
|
410
|
-
debug('rabbit: new channel got', { connectionPurpose, channel: this.channel });
|
|
397
|
+
const channel = await this.getNewChannel({});
|
|
411
398
|
channel.on('error', (err) => {
|
|
412
399
|
logger.error('rabbit: channel error', { err });
|
|
413
400
|
});
|
|
@@ -421,8 +408,9 @@ class RabbitMq implements IAfRabbitMq {
|
|
|
421
408
|
return this.publishChannelSetupPromise;
|
|
422
409
|
}
|
|
423
410
|
|
|
424
|
-
async assertExchange(exchangeName: string, options
|
|
425
|
-
const channel: ChannelWrapper = await this.assertChannel(
|
|
411
|
+
async assertExchange(exchangeName: string, options?: any) {
|
|
412
|
+
const channel: ChannelWrapper = await this.assertChannel();
|
|
413
|
+
|
|
426
414
|
if (this.exchanges[exchangeName]) {
|
|
427
415
|
delete this.assertExchangePromises[exchangeName];
|
|
428
416
|
return this.exchanges[exchangeName];
|
|
@@ -437,33 +425,32 @@ class RabbitMq implements IAfRabbitMq {
|
|
|
437
425
|
return this.exchanges[exchangeName];
|
|
438
426
|
}
|
|
439
427
|
|
|
440
|
-
async getQueueLength(queue: string
|
|
428
|
+
async getQueueLength(queue: string) {
|
|
441
429
|
RabbitMq.validateName('queue', queue);
|
|
442
|
-
const { connection } = this.connectionsMap[connectionPurpose];
|
|
443
430
|
const { channel } = this;
|
|
444
431
|
if (!channel) {
|
|
445
432
|
throw new Error('channel is not defined');
|
|
446
433
|
}
|
|
447
|
-
debug('rabbit: getting queue length', { queue, connected: connection?.isConnected() });
|
|
434
|
+
debug('rabbit: getting queue length', { queue, connected: this.connection?.isConnected() });
|
|
448
435
|
return channel?.checkQueue(queue);
|
|
449
436
|
}
|
|
450
437
|
|
|
451
|
-
private async deleteQueue(queue: string
|
|
438
|
+
private async deleteQueue(queue: string) {
|
|
452
439
|
RabbitMq.validateName('queue', queue);
|
|
453
|
-
const channel: ChannelWrapper = await this.assertChannel(
|
|
440
|
+
const channel: ChannelWrapper = await this.assertChannel();
|
|
454
441
|
logger.info('rabbit: deleting queue', { queue });
|
|
455
442
|
const deleteQueueRes = await channel.deleteQueue(queue);
|
|
456
443
|
debug('queue deleted', deleteQueueRes);
|
|
457
444
|
return deleteQueueRes;
|
|
458
445
|
}
|
|
459
446
|
|
|
460
|
-
async bindQueue(queue: string, exchange: string
|
|
461
|
-
const channel: ChannelWrapper = await this.assertChannel(
|
|
447
|
+
async bindQueue(queue: string, exchange: string) {
|
|
448
|
+
const channel: ChannelWrapper = await this.assertChannel();
|
|
462
449
|
await channel.addSetup((setupChannel: ConfirmChannel) => setupChannel.bindQueue(queue, exchange, ''));
|
|
463
450
|
return channel.bindQueue(queue, exchange, '');
|
|
464
451
|
}
|
|
465
452
|
|
|
466
|
-
async setupQueue(queueName: string,
|
|
453
|
+
async setupQueue(queueName: string, options?: Options.AssertQueue): Promise<Replies.AssertQueue> {
|
|
467
454
|
let queue: Replies.AssertQueue;
|
|
468
455
|
const shouldUseQuorum = RabbitMq.shouldUseQuorum(queueName);
|
|
469
456
|
const localeOptions = {
|
|
@@ -476,7 +463,7 @@ class RabbitMq implements IAfRabbitMq {
|
|
|
476
463
|
},
|
|
477
464
|
};
|
|
478
465
|
try {
|
|
479
|
-
const channel: ChannelWrapper = await this.assertChannel(
|
|
466
|
+
const channel: ChannelWrapper = await this.assertChannel();
|
|
480
467
|
debug('assertQueue->channel.addSetup', { queueName });
|
|
481
468
|
await channel.addSetup((setupChannel: ConfirmChannel) => setupChannel.assertQueue(queueName, localeOptions));
|
|
482
469
|
debug('assertQueue->channel.assertQueue', { queueName });
|
|
@@ -485,8 +472,8 @@ class RabbitMq implements IAfRabbitMq {
|
|
|
485
472
|
logger.error('rabbit: assertQueue error', { queueName, options, error: e });
|
|
486
473
|
if (!this.options?.dontRetryAssert) {
|
|
487
474
|
debug('retrying assertQueue', { queueName });
|
|
488
|
-
const channel = await this.assertChannel({ force: true
|
|
489
|
-
await this.deleteQueue(queueName
|
|
475
|
+
const channel = await this.assertChannel({ force: true });
|
|
476
|
+
await this.deleteQueue(queueName);
|
|
490
477
|
|
|
491
478
|
debug('retrying assertQueue->channel.addSetup', { queueName });
|
|
492
479
|
await channel.addSetup((setupChannel: ConfirmChannel) => setupChannel.assertQueue(queueName, localeOptions));
|
|
@@ -516,8 +503,7 @@ class RabbitMq implements IAfRabbitMq {
|
|
|
516
503
|
return false;
|
|
517
504
|
}
|
|
518
505
|
|
|
519
|
-
async assertQueue(queueName: string,
|
|
520
|
-
debug('rabbit: start assert queue', { connectionPurpose, queueName });
|
|
506
|
+
async assertQueue(queueName: string, options?: Options.AssertQueue): Promise<any> {
|
|
521
507
|
RabbitMq.validateName('queue', queueName);
|
|
522
508
|
if (this.queues[queueName]) {
|
|
523
509
|
delete this.queueSetupPromises[queueName];
|
|
@@ -528,13 +514,12 @@ class RabbitMq implements IAfRabbitMq {
|
|
|
528
514
|
return this.queueSetupPromises[queueName];
|
|
529
515
|
}
|
|
530
516
|
|
|
531
|
-
this.queueSetupPromises[queueName] = this.setupQueue(queueName,
|
|
532
|
-
debug('rabbit: done assert queue', { connectionPurpose, queueName });
|
|
517
|
+
this.queueSetupPromises[queueName] = this.setupQueue(queueName, options);
|
|
533
518
|
return this.queueSetupPromises[queueName];
|
|
534
519
|
}
|
|
535
520
|
|
|
536
521
|
private saveConsumer(queue: string, callback: CallbackFunction, options: ConsumeOptions | undefined) {
|
|
537
|
-
const isConsumerExist:
|
|
522
|
+
const isConsumerExist :boolean = this.consumers.some((consumer) => consumer.queue === queue);
|
|
538
523
|
if (!isConsumerExist) {
|
|
539
524
|
logger.info(`rabbit: consumer: ${queue} saved in consumer array`);
|
|
540
525
|
this.consumers.push({
|
|
@@ -583,9 +568,9 @@ class RabbitMq implements IAfRabbitMq {
|
|
|
583
568
|
}
|
|
584
569
|
logger.info(`rabbit: Consuming with lock from queue ${queue} with lockTimeout: ${lockTimeout}ms`);
|
|
585
570
|
}
|
|
586
|
-
const channel = await this.getNewChannel({
|
|
571
|
+
const channel = await this.getNewChannel({});
|
|
587
572
|
return channel.addSetup(async (confirmChannel: ConfirmChannel) => {
|
|
588
|
-
const q = await this.assertQueue(queue,
|
|
573
|
+
const q = await this.assertQueue(queue, optionsWithDefaults);
|
|
589
574
|
await confirmChannel.prefetch(limit, false);
|
|
590
575
|
const { consumerTag } = await confirmChannel.consume(
|
|
591
576
|
queue,
|
|
@@ -673,13 +658,13 @@ class RabbitMq implements IAfRabbitMq {
|
|
|
673
658
|
});
|
|
674
659
|
}
|
|
675
660
|
|
|
676
|
-
async consumeFromExchange(queue: string, exchange: string, callback: CallbackFunction, options?: ConsumeOptions): Promise<any> {
|
|
661
|
+
async consumeFromExchange(queue: string, exchange: string, callback: CallbackFunction, options?: ConsumeOptions) : Promise<any> {
|
|
677
662
|
const optionsWithDefaults = { ...DEFAULT_OPTIONS, ...options };
|
|
678
663
|
RabbitMq.validateName('exchange', exchange);
|
|
679
664
|
RabbitMq.validateName('queue', queue);
|
|
680
665
|
const { limit, deadMessageTtl } = optionsWithDefaults;
|
|
681
666
|
await this.saveConsumer(queue, callback, options);
|
|
682
|
-
const channel: ChannelWrapper = await this.getNewChannel({ name: `consume
|
|
667
|
+
const channel: ChannelWrapper = await this.getNewChannel({ name: `consume-exchange-${exchange}-queue-${queue}` });
|
|
683
668
|
|
|
684
669
|
return channel.addSetup(async (c: ConfirmChannel) => {
|
|
685
670
|
const assertExchange = await assertExchangeFanout(c, exchange);
|
|
@@ -697,11 +682,11 @@ class RabbitMq implements IAfRabbitMq {
|
|
|
697
682
|
});
|
|
698
683
|
}
|
|
699
684
|
|
|
700
|
-
async publish(exchange: string, content: any, customHeaders?: any): Promise<boolean> {
|
|
685
|
+
async publish(exchange: string, content: any, customHeaders?: any) : Promise<boolean> {
|
|
701
686
|
return wrapSetImmediate(async () => {
|
|
702
687
|
RabbitMq.validateName('exchange', exchange);
|
|
703
|
-
const channel: ChannelWrapper = await this.assertChannel(
|
|
704
|
-
await this.assertExchange(exchange
|
|
688
|
+
const channel: ChannelWrapper = await this.assertChannel();
|
|
689
|
+
await this.assertExchange(exchange);
|
|
705
690
|
await channel.publish(exchange, '',
|
|
706
691
|
Buffer.from(JSON.stringify(content)),
|
|
707
692
|
RabbitMq.getPublishOptions(customHeaders));
|
|
@@ -715,7 +700,7 @@ class RabbitMq implements IAfRabbitMq {
|
|
|
715
700
|
customHeaders?: any,
|
|
716
701
|
): Promise<boolean | undefined> {
|
|
717
702
|
try {
|
|
718
|
-
await this.assertChannel(
|
|
703
|
+
await this.assertChannel();
|
|
719
704
|
} catch (e) {
|
|
720
705
|
logger.error(`rabbit sendToQueue: failed to send assert channel when sending to queue ${queue}`, { e });
|
|
721
706
|
throw e;
|
|
@@ -723,7 +708,7 @@ class RabbitMq implements IAfRabbitMq {
|
|
|
723
708
|
|
|
724
709
|
try {
|
|
725
710
|
RabbitMq.validateName('queue', queue);
|
|
726
|
-
await this.assertQueue(queue,
|
|
711
|
+
await this.assertQueue(queue, options);
|
|
727
712
|
} catch (e) {
|
|
728
713
|
logger.error(`rabbit sendToQueue: failed to assert queue ${queue}`, { e });
|
|
729
714
|
throw e;
|
|
@@ -736,41 +721,34 @@ class RabbitMq implements IAfRabbitMq {
|
|
|
736
721
|
debug(`rabbit: sending to queue ${queue}`, { res });
|
|
737
722
|
return res;
|
|
738
723
|
} catch (e) {
|
|
739
|
-
|
|
724
|
+
const isConnected = await this.isConnected();
|
|
725
|
+
logger.error(`rabbit sendToQueue: failed to send to queue ${queue}, isConnected: ${isConnected}`, { e });
|
|
740
726
|
throw e;
|
|
741
727
|
}
|
|
742
728
|
}
|
|
743
729
|
|
|
744
|
-
async isConnected(): Promise<boolean> {
|
|
745
|
-
const
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
logger.error('rabbit: isConnected - false');
|
|
764
|
-
return false;
|
|
765
|
-
}
|
|
766
|
-
logger.info('rabbit: isConnected - true');
|
|
767
|
-
return true;
|
|
768
|
-
}),
|
|
769
|
-
);
|
|
770
|
-
return isEachConnectionConnected.every((isConnected) => isConnected === true);
|
|
730
|
+
async isConnected() : Promise<boolean> {
|
|
731
|
+
const connection = await this.getConnection();
|
|
732
|
+
const isConnected = connection.isConnected();
|
|
733
|
+
if (!isConnected) {
|
|
734
|
+
logger.error('rabbit: isConnected - false');
|
|
735
|
+
return false;
|
|
736
|
+
}
|
|
737
|
+
const channel: any = await this.assertChannel();
|
|
738
|
+
try {
|
|
739
|
+
await Promise.all([
|
|
740
|
+
channel.waitForConnect(),
|
|
741
|
+
...this.consumers.map((c: AfConsumer) => channel.checkQueue(c.queue)),
|
|
742
|
+
]);
|
|
743
|
+
} catch (e) {
|
|
744
|
+
logger.error('rabbit: isConnected - false');
|
|
745
|
+
return false;
|
|
746
|
+
}
|
|
747
|
+
logger.info('rabbit: isConnected - true');
|
|
748
|
+
return true;
|
|
771
749
|
}
|
|
772
750
|
|
|
773
|
-
async gracefulShutdown(signal: string): Promise<void> {
|
|
751
|
+
async gracefulShutdown(signal: string) : Promise<void> {
|
|
774
752
|
const tagsNumber = this.consumersTags.length;
|
|
775
753
|
logger.info(`rabbit: [gracefully-shutdown] received ${signal}! canceling #${tagsNumber} tags...`);
|
|
776
754
|
const cancelTagPromises = this.consumersTags.map(([channel, tag]) => channel.cancel(tag));
|
package/src/lib/consts.ts
CHANGED
package/src/lib/types.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { AmqpConnectionManager } from 'amqp-connection-manager';
|
|
2
1
|
import { ConsumeMessage, Options, Replies } from 'amqplib';
|
|
3
2
|
|
|
4
3
|
export interface ExchangesCache {
|
|
@@ -60,8 +59,3 @@ export const CONSUMER_DEFAULT_OPTIONS: Options.Consume = {
|
|
|
60
59
|
[HA_PROMOTE_ON_SHUTDOWN]: 'always',
|
|
61
60
|
},
|
|
62
61
|
};
|
|
63
|
-
|
|
64
|
-
export type ConnectionData = {
|
|
65
|
-
connection: AmqpConnectionManager | null;
|
|
66
|
-
creatingConnection: boolean;
|
|
67
|
-
};
|