@autofleet/rabbit 3.2.24-beta.0 → 3.2.24-beta.10
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 +66 -77
- 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 +1 -1
- package/src/index.ts +83 -101
- 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,11 +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
|
-
|
|
184
|
+
this.connection = connection;
|
|
185
|
+
this.connection.on('error', (err) => {
|
|
189
186
|
logger_1.default.error('rabbit: connection error', { err });
|
|
190
187
|
if (!isResolved) {
|
|
191
188
|
isResolved = true;
|
|
@@ -193,7 +190,7 @@ class RabbitMq {
|
|
|
193
190
|
this.em.emit(consts_1.CONNECTION_FAILED_CONST, err);
|
|
194
191
|
}
|
|
195
192
|
});
|
|
196
|
-
|
|
193
|
+
this.connection.on('connectFailed', (err) => {
|
|
197
194
|
this.consumersTags = [];
|
|
198
195
|
logger_1.default.error('rabbit: connection connectFailed', { err });
|
|
199
196
|
if (!isResolved) {
|
|
@@ -202,7 +199,8 @@ class RabbitMq {
|
|
|
202
199
|
this.em.emit(consts_1.CONNECTION_FAILED_CONST, err);
|
|
203
200
|
}
|
|
204
201
|
});
|
|
205
|
-
|
|
202
|
+
this.connection.on('disconnect', ({ err }) => {
|
|
203
|
+
// this.channel = null;
|
|
206
204
|
this.consumersTags = [];
|
|
207
205
|
debug('rabbit: connection closed');
|
|
208
206
|
if (this.options?.disableReconnect) {
|
|
@@ -213,26 +211,24 @@ class RabbitMq {
|
|
|
213
211
|
logger_1.default.error(`${this.RECONNECT_MSG}${err && ` - ${err}`}`);
|
|
214
212
|
}
|
|
215
213
|
});
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
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);
|
|
219
218
|
isResolved = true;
|
|
220
|
-
resolve(
|
|
219
|
+
resolve(connection);
|
|
221
220
|
});
|
|
222
221
|
});
|
|
223
222
|
}
|
|
224
|
-
async getNewChannel({ name = (0, utils_1.rand)().toString(), onClose = null, options = {}
|
|
223
|
+
async getNewChannel({ name = (0, utils_1.rand)().toString(), onClose = null, options = {} } = {}) {
|
|
225
224
|
let connection;
|
|
226
225
|
try {
|
|
227
|
-
connection = await this.getConnection(
|
|
226
|
+
connection = await this.getConnection();
|
|
228
227
|
}
|
|
229
228
|
catch (e) {
|
|
230
229
|
logger_1.default.error(`rabbit: error on get connection for new channel ${name} `, { e });
|
|
231
230
|
throw e;
|
|
232
231
|
}
|
|
233
|
-
if (!connection) {
|
|
234
|
-
throw new Error(`rabbit: couldnt get connection for new channel ${name}`);
|
|
235
|
-
}
|
|
236
232
|
const channel = connection.createChannel({ ...options });
|
|
237
233
|
(0, events_1.once)(channel, 'close').then((args) => {
|
|
238
234
|
logger_1.default.error(`rabbit: channel ${name} closed`);
|
|
@@ -248,15 +244,14 @@ class RabbitMq {
|
|
|
248
244
|
throw err;
|
|
249
245
|
}
|
|
250
246
|
}
|
|
251
|
-
async assertChannel({ force = false
|
|
247
|
+
async assertChannel({ force = false } = {}) {
|
|
252
248
|
if (!this.publishChannelSetupPromise) {
|
|
253
249
|
this.publishChannelSetupPromise = new Promise(async (resolve, reject) => {
|
|
254
250
|
if (this.channel && !force) {
|
|
255
251
|
return resolve(this.channel);
|
|
256
252
|
}
|
|
257
253
|
try {
|
|
258
|
-
const channel = await this.getNewChannel({
|
|
259
|
-
debug('rabbit: new channel got', { connectionPurpose, channel: this.channel });
|
|
254
|
+
const channel = await this.getNewChannel({});
|
|
260
255
|
channel.on('error', (err) => {
|
|
261
256
|
logger_1.default.error('rabbit: channel error', { err });
|
|
262
257
|
});
|
|
@@ -270,8 +265,8 @@ class RabbitMq {
|
|
|
270
265
|
}
|
|
271
266
|
return this.publishChannelSetupPromise;
|
|
272
267
|
}
|
|
273
|
-
async assertExchange(exchangeName, options
|
|
274
|
-
const channel = await this.assertChannel(
|
|
268
|
+
async assertExchange(exchangeName, options) {
|
|
269
|
+
const channel = await this.assertChannel();
|
|
275
270
|
if (this.exchanges[exchangeName]) {
|
|
276
271
|
delete this.assertExchangePromises[exchangeName];
|
|
277
272
|
return this.exchanges[exchangeName];
|
|
@@ -283,30 +278,29 @@ class RabbitMq {
|
|
|
283
278
|
this.exchanges[exchangeName] = await this.assertExchangePromises[exchangeName];
|
|
284
279
|
return this.exchanges[exchangeName];
|
|
285
280
|
}
|
|
286
|
-
async getQueueLength(queue
|
|
281
|
+
async getQueueLength(queue) {
|
|
287
282
|
RabbitMq.validateName('queue', queue);
|
|
288
|
-
const { connection } = this.connectionsMap[connectionPurpose];
|
|
289
283
|
const { channel } = this;
|
|
290
284
|
if (!channel) {
|
|
291
285
|
throw new Error('channel is not defined');
|
|
292
286
|
}
|
|
293
|
-
debug('rabbit: getting queue length', { queue, connected: connection?.isConnected() });
|
|
287
|
+
debug('rabbit: getting queue length', { queue, connected: this.connection?.isConnected() });
|
|
294
288
|
return channel?.checkQueue(queue);
|
|
295
289
|
}
|
|
296
|
-
async deleteQueue(queue
|
|
290
|
+
async deleteQueue(queue) {
|
|
297
291
|
RabbitMq.validateName('queue', queue);
|
|
298
|
-
const channel = await this.assertChannel(
|
|
292
|
+
const channel = await this.assertChannel();
|
|
299
293
|
logger_1.default.info('rabbit: deleting queue', { queue });
|
|
300
294
|
const deleteQueueRes = await channel.deleteQueue(queue);
|
|
301
295
|
debug('queue deleted', deleteQueueRes);
|
|
302
296
|
return deleteQueueRes;
|
|
303
297
|
}
|
|
304
|
-
async bindQueue(queue, exchange
|
|
305
|
-
const channel = await this.assertChannel(
|
|
298
|
+
async bindQueue(queue, exchange) {
|
|
299
|
+
const channel = await this.assertChannel();
|
|
306
300
|
await channel.addSetup((setupChannel) => setupChannel.bindQueue(queue, exchange, ''));
|
|
307
301
|
return channel.bindQueue(queue, exchange, '');
|
|
308
302
|
}
|
|
309
|
-
async setupQueue(queueName,
|
|
303
|
+
async setupQueue(queueName, options) {
|
|
310
304
|
let queue;
|
|
311
305
|
const shouldUseQuorum = RabbitMq.shouldUseQuorum(queueName);
|
|
312
306
|
const localeOptions = {
|
|
@@ -319,7 +313,7 @@ class RabbitMq {
|
|
|
319
313
|
},
|
|
320
314
|
};
|
|
321
315
|
try {
|
|
322
|
-
const channel = await this.assertChannel(
|
|
316
|
+
const channel = await this.assertChannel();
|
|
323
317
|
debug('assertQueue->channel.addSetup', { queueName });
|
|
324
318
|
await channel.addSetup((setupChannel) => setupChannel.assertQueue(queueName, localeOptions));
|
|
325
319
|
debug('assertQueue->channel.assertQueue', { queueName });
|
|
@@ -329,8 +323,8 @@ class RabbitMq {
|
|
|
329
323
|
logger_1.default.error('rabbit: assertQueue error', { queueName, options, error: e });
|
|
330
324
|
if (!this.options?.dontRetryAssert) {
|
|
331
325
|
debug('retrying assertQueue', { queueName });
|
|
332
|
-
const channel = await this.assertChannel({ force: true
|
|
333
|
-
await this.deleteQueue(queueName
|
|
326
|
+
const channel = await this.assertChannel({ force: true });
|
|
327
|
+
await this.deleteQueue(queueName);
|
|
334
328
|
debug('retrying assertQueue->channel.addSetup', { queueName });
|
|
335
329
|
await channel.addSetup((setupChannel) => setupChannel.assertQueue(queueName, localeOptions));
|
|
336
330
|
debug('retrying assertQueue->channel.assertQueue', { queueName });
|
|
@@ -354,7 +348,7 @@ class RabbitMq {
|
|
|
354
348
|
}
|
|
355
349
|
return false;
|
|
356
350
|
}
|
|
357
|
-
async assertQueue(queueName,
|
|
351
|
+
async assertQueue(queueName, options) {
|
|
358
352
|
RabbitMq.validateName('queue', queueName);
|
|
359
353
|
if (this.queues[queueName]) {
|
|
360
354
|
delete this.queueSetupPromises[queueName];
|
|
@@ -363,7 +357,7 @@ class RabbitMq {
|
|
|
363
357
|
if (this.queueSetupPromises[queueName]) {
|
|
364
358
|
return this.queueSetupPromises[queueName];
|
|
365
359
|
}
|
|
366
|
-
this.queueSetupPromises[queueName] = this.setupQueue(queueName,
|
|
360
|
+
this.queueSetupPromises[queueName] = this.setupQueue(queueName, options);
|
|
367
361
|
return this.queueSetupPromises[queueName];
|
|
368
362
|
}
|
|
369
363
|
saveConsumer(queue, callback, options) {
|
|
@@ -406,9 +400,9 @@ class RabbitMq {
|
|
|
406
400
|
}
|
|
407
401
|
logger_1.default.info(`rabbit: Consuming with lock from queue ${queue} with lockTimeout: ${lockTimeout}ms`);
|
|
408
402
|
}
|
|
409
|
-
const channel = await this.getNewChannel({
|
|
403
|
+
const channel = await this.getNewChannel({});
|
|
410
404
|
return channel.addSetup(async (confirmChannel) => {
|
|
411
|
-
const q = await this.assertQueue(queue,
|
|
405
|
+
const q = await this.assertQueue(queue, optionsWithDefaults);
|
|
412
406
|
await confirmChannel.prefetch(limit, false);
|
|
413
407
|
const { consumerTag } = await confirmChannel.consume(queue, async (msg) => {
|
|
414
408
|
if (!msg) {
|
|
@@ -490,12 +484,12 @@ class RabbitMq {
|
|
|
490
484
|
RabbitMq.validateName('queue', queue);
|
|
491
485
|
const { limit, deadMessageTtl } = optionsWithDefaults;
|
|
492
486
|
await this.saveConsumer(queue, callback, options);
|
|
493
|
-
const channel = await this.getNewChannel({ name: `consume
|
|
487
|
+
const channel = await this.getNewChannel({ name: `consume-exchange-${exchange}-queue-${queue}` });
|
|
494
488
|
return channel.addSetup(async (c) => {
|
|
495
489
|
const assertExchange = await (0, utils_1.assertExchangeFanout)(c, exchange);
|
|
496
490
|
await c.assertQueue(queue);
|
|
497
491
|
this.exchanges[exchange] = assertExchange;
|
|
498
|
-
await c.prefetch(limit,
|
|
492
|
+
await c.prefetch(limit, false);
|
|
499
493
|
return Promise.all([
|
|
500
494
|
c.bindQueue(queue, exchange, ''),
|
|
501
495
|
this.consume(queue, callback, options),
|
|
@@ -505,14 +499,14 @@ class RabbitMq {
|
|
|
505
499
|
async publish(exchange, content, customHeaders) {
|
|
506
500
|
return (0, utils_1.wrapSetImmediate)(async () => {
|
|
507
501
|
RabbitMq.validateName('exchange', exchange);
|
|
508
|
-
const channel = await this.assertChannel(
|
|
509
|
-
await this.assertExchange(exchange
|
|
502
|
+
const channel = await this.assertChannel();
|
|
503
|
+
await this.assertExchange(exchange);
|
|
510
504
|
await channel.publish(exchange, '', Buffer.from(JSON.stringify(content)), RabbitMq.getPublishOptions(customHeaders));
|
|
511
505
|
});
|
|
512
506
|
}
|
|
513
507
|
async sendToQueue(queue, content, options, customHeaders) {
|
|
514
508
|
try {
|
|
515
|
-
await this.assertChannel(
|
|
509
|
+
await this.assertChannel();
|
|
516
510
|
}
|
|
517
511
|
catch (e) {
|
|
518
512
|
logger_1.default.error(`rabbit sendToQueue: failed to send assert channel when sending to queue ${queue}`, { e });
|
|
@@ -520,7 +514,7 @@ class RabbitMq {
|
|
|
520
514
|
}
|
|
521
515
|
try {
|
|
522
516
|
RabbitMq.validateName('queue', queue);
|
|
523
|
-
await this.assertQueue(queue,
|
|
517
|
+
await this.assertQueue(queue, options);
|
|
524
518
|
}
|
|
525
519
|
catch (e) {
|
|
526
520
|
logger_1.default.error(`rabbit sendToQueue: failed to assert queue ${queue}`, { e });
|
|
@@ -532,36 +526,31 @@ class RabbitMq {
|
|
|
532
526
|
return res;
|
|
533
527
|
}
|
|
534
528
|
catch (e) {
|
|
535
|
-
|
|
529
|
+
const isConnected = await this.isConnected();
|
|
530
|
+
logger_1.default.error(`rabbit sendToQueue: failed to send to queue ${queue}, isConnected: ${isConnected}`, { e });
|
|
536
531
|
throw e;
|
|
537
532
|
}
|
|
538
533
|
}
|
|
539
534
|
async isConnected() {
|
|
540
|
-
const
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
return false;
|
|
560
|
-
}
|
|
561
|
-
logger_1.default.info('rabbit: isConnected - true');
|
|
562
|
-
return true;
|
|
563
|
-
}));
|
|
564
|
-
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;
|
|
565
554
|
}
|
|
566
555
|
async gracefulShutdown(signal) {
|
|
567
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
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,13 +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
|
-
newConnection.on('error', (err) => {
|
|
324
|
+
this.connection = connection;
|
|
325
|
+
this.connection.on('error', (err) => {
|
|
334
326
|
logger.error('rabbit: connection error', { err });
|
|
335
327
|
if (!isResolved) {
|
|
336
328
|
isResolved = true;
|
|
@@ -339,7 +331,7 @@ class RabbitMq implements IAfRabbitMq {
|
|
|
339
331
|
}
|
|
340
332
|
});
|
|
341
333
|
|
|
342
|
-
|
|
334
|
+
this.connection.on('connectFailed', (err) => {
|
|
343
335
|
this.consumersTags = [];
|
|
344
336
|
logger.error('rabbit: connection connectFailed', { err });
|
|
345
337
|
if (!isResolved) {
|
|
@@ -349,7 +341,8 @@ class RabbitMq implements IAfRabbitMq {
|
|
|
349
341
|
}
|
|
350
342
|
});
|
|
351
343
|
|
|
352
|
-
|
|
344
|
+
this.connection.on('disconnect', ({ err }) => {
|
|
345
|
+
// this.channel = null;
|
|
353
346
|
this.consumersTags = [];
|
|
354
347
|
debug('rabbit: connection closed');
|
|
355
348
|
if (this.options?.disableReconnect) {
|
|
@@ -359,28 +352,25 @@ class RabbitMq implements IAfRabbitMq {
|
|
|
359
352
|
logger.error(`${this.RECONNECT_MSG}${err && ` - ${err}`}`);
|
|
360
353
|
}
|
|
361
354
|
});
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
355
|
+
|
|
356
|
+
this.connection.once('connect', async () => {
|
|
357
|
+
debug('rabbit: connection established');
|
|
358
|
+
this.creatingConnection = false;
|
|
359
|
+
this.em.emit(CONNECTION_CREATED_CONST, connection);
|
|
365
360
|
isResolved = true;
|
|
366
|
-
resolve(
|
|
361
|
+
resolve(connection);
|
|
367
362
|
});
|
|
368
363
|
});
|
|
369
364
|
}
|
|
370
365
|
|
|
371
|
-
async getNewChannel({
|
|
372
|
-
|
|
373
|
-
}: newChannelOpts): Promise<ChannelWrapper> {
|
|
374
|
-
let connection!: AmqpConnectionManager | undefined | null;
|
|
366
|
+
async getNewChannel({ name = rand().toString(), onClose = null, options = {} }: newChannelOpts = {}) {
|
|
367
|
+
let connection!: AmqpConnectionManager;
|
|
375
368
|
try {
|
|
376
|
-
connection = await this.getConnection(
|
|
369
|
+
connection = await this.getConnection();
|
|
377
370
|
} catch (e) {
|
|
378
371
|
logger.error(`rabbit: error on get connection for new channel ${name} `, { e });
|
|
379
372
|
throw e;
|
|
380
373
|
}
|
|
381
|
-
if (!connection) {
|
|
382
|
-
throw new Error(`rabbit: couldnt get connection for new channel ${name}`);
|
|
383
|
-
}
|
|
384
374
|
const channel = connection.createChannel({ ...options });
|
|
385
375
|
once(channel, 'close').then((args) => {
|
|
386
376
|
logger.error(`rabbit: channel ${name} closed`);
|
|
@@ -396,7 +386,7 @@ class RabbitMq implements IAfRabbitMq {
|
|
|
396
386
|
}
|
|
397
387
|
}
|
|
398
388
|
|
|
399
|
-
async assertChannel({ force = false
|
|
389
|
+
async assertChannel({ force = false } : assertChannelOpts = {}): Promise<ChannelWrapper> {
|
|
400
390
|
if (!this.publishChannelSetupPromise) {
|
|
401
391
|
this.publishChannelSetupPromise = new Promise<ChannelWrapper>(async (resolve, reject) => {
|
|
402
392
|
if (this.channel && !force) {
|
|
@@ -404,8 +394,7 @@ class RabbitMq implements IAfRabbitMq {
|
|
|
404
394
|
}
|
|
405
395
|
|
|
406
396
|
try {
|
|
407
|
-
const channel = await this.getNewChannel({
|
|
408
|
-
debug('rabbit: new channel got', { connectionPurpose, channel: this.channel });
|
|
397
|
+
const channel = await this.getNewChannel({});
|
|
409
398
|
channel.on('error', (err) => {
|
|
410
399
|
logger.error('rabbit: channel error', { err });
|
|
411
400
|
});
|
|
@@ -419,8 +408,9 @@ class RabbitMq implements IAfRabbitMq {
|
|
|
419
408
|
return this.publishChannelSetupPromise;
|
|
420
409
|
}
|
|
421
410
|
|
|
422
|
-
async assertExchange(exchangeName: string, options
|
|
423
|
-
const channel: ChannelWrapper = await this.assertChannel(
|
|
411
|
+
async assertExchange(exchangeName: string, options?: any) {
|
|
412
|
+
const channel: ChannelWrapper = await this.assertChannel();
|
|
413
|
+
|
|
424
414
|
if (this.exchanges[exchangeName]) {
|
|
425
415
|
delete this.assertExchangePromises[exchangeName];
|
|
426
416
|
return this.exchanges[exchangeName];
|
|
@@ -435,33 +425,32 @@ class RabbitMq implements IAfRabbitMq {
|
|
|
435
425
|
return this.exchanges[exchangeName];
|
|
436
426
|
}
|
|
437
427
|
|
|
438
|
-
async getQueueLength(queue: string
|
|
428
|
+
async getQueueLength(queue: string) {
|
|
439
429
|
RabbitMq.validateName('queue', queue);
|
|
440
|
-
const { connection } = this.connectionsMap[connectionPurpose];
|
|
441
430
|
const { channel } = this;
|
|
442
431
|
if (!channel) {
|
|
443
432
|
throw new Error('channel is not defined');
|
|
444
433
|
}
|
|
445
|
-
debug('rabbit: getting queue length', { queue, connected: connection?.isConnected() });
|
|
434
|
+
debug('rabbit: getting queue length', { queue, connected: this.connection?.isConnected() });
|
|
446
435
|
return channel?.checkQueue(queue);
|
|
447
436
|
}
|
|
448
437
|
|
|
449
|
-
private async deleteQueue(queue: string
|
|
438
|
+
private async deleteQueue(queue: string) {
|
|
450
439
|
RabbitMq.validateName('queue', queue);
|
|
451
|
-
const channel: ChannelWrapper = await this.assertChannel(
|
|
440
|
+
const channel: ChannelWrapper = await this.assertChannel();
|
|
452
441
|
logger.info('rabbit: deleting queue', { queue });
|
|
453
442
|
const deleteQueueRes = await channel.deleteQueue(queue);
|
|
454
443
|
debug('queue deleted', deleteQueueRes);
|
|
455
444
|
return deleteQueueRes;
|
|
456
445
|
}
|
|
457
446
|
|
|
458
|
-
async bindQueue(queue: string, exchange: string
|
|
459
|
-
const channel: ChannelWrapper = await this.assertChannel(
|
|
447
|
+
async bindQueue(queue: string, exchange: string) {
|
|
448
|
+
const channel: ChannelWrapper = await this.assertChannel();
|
|
460
449
|
await channel.addSetup((setupChannel: ConfirmChannel) => setupChannel.bindQueue(queue, exchange, ''));
|
|
461
450
|
return channel.bindQueue(queue, exchange, '');
|
|
462
451
|
}
|
|
463
452
|
|
|
464
|
-
async setupQueue(queueName: string,
|
|
453
|
+
async setupQueue(queueName: string, options?: Options.AssertQueue): Promise<Replies.AssertQueue> {
|
|
465
454
|
let queue: Replies.AssertQueue;
|
|
466
455
|
const shouldUseQuorum = RabbitMq.shouldUseQuorum(queueName);
|
|
467
456
|
const localeOptions = {
|
|
@@ -474,7 +463,7 @@ class RabbitMq implements IAfRabbitMq {
|
|
|
474
463
|
},
|
|
475
464
|
};
|
|
476
465
|
try {
|
|
477
|
-
const channel: ChannelWrapper = await this.assertChannel(
|
|
466
|
+
const channel: ChannelWrapper = await this.assertChannel();
|
|
478
467
|
debug('assertQueue->channel.addSetup', { queueName });
|
|
479
468
|
await channel.addSetup((setupChannel: ConfirmChannel) => setupChannel.assertQueue(queueName, localeOptions));
|
|
480
469
|
debug('assertQueue->channel.assertQueue', { queueName });
|
|
@@ -483,8 +472,8 @@ class RabbitMq implements IAfRabbitMq {
|
|
|
483
472
|
logger.error('rabbit: assertQueue error', { queueName, options, error: e });
|
|
484
473
|
if (!this.options?.dontRetryAssert) {
|
|
485
474
|
debug('retrying assertQueue', { queueName });
|
|
486
|
-
const channel = await this.assertChannel({ force: true
|
|
487
|
-
await this.deleteQueue(queueName
|
|
475
|
+
const channel = await this.assertChannel({ force: true });
|
|
476
|
+
await this.deleteQueue(queueName);
|
|
488
477
|
|
|
489
478
|
debug('retrying assertQueue->channel.addSetup', { queueName });
|
|
490
479
|
await channel.addSetup((setupChannel: ConfirmChannel) => setupChannel.assertQueue(queueName, localeOptions));
|
|
@@ -514,7 +503,7 @@ class RabbitMq implements IAfRabbitMq {
|
|
|
514
503
|
return false;
|
|
515
504
|
}
|
|
516
505
|
|
|
517
|
-
async assertQueue(queueName: string,
|
|
506
|
+
async assertQueue(queueName: string, options?: Options.AssertQueue): Promise<any> {
|
|
518
507
|
RabbitMq.validateName('queue', queueName);
|
|
519
508
|
if (this.queues[queueName]) {
|
|
520
509
|
delete this.queueSetupPromises[queueName];
|
|
@@ -525,12 +514,12 @@ class RabbitMq implements IAfRabbitMq {
|
|
|
525
514
|
return this.queueSetupPromises[queueName];
|
|
526
515
|
}
|
|
527
516
|
|
|
528
|
-
this.queueSetupPromises[queueName] = this.setupQueue(queueName,
|
|
517
|
+
this.queueSetupPromises[queueName] = this.setupQueue(queueName, options);
|
|
529
518
|
return this.queueSetupPromises[queueName];
|
|
530
519
|
}
|
|
531
520
|
|
|
532
521
|
private saveConsumer(queue: string, callback: CallbackFunction, options: ConsumeOptions | undefined) {
|
|
533
|
-
const isConsumerExist:
|
|
522
|
+
const isConsumerExist :boolean = this.consumers.some((consumer) => consumer.queue === queue);
|
|
534
523
|
if (!isConsumerExist) {
|
|
535
524
|
logger.info(`rabbit: consumer: ${queue} saved in consumer array`);
|
|
536
525
|
this.consumers.push({
|
|
@@ -579,9 +568,9 @@ class RabbitMq implements IAfRabbitMq {
|
|
|
579
568
|
}
|
|
580
569
|
logger.info(`rabbit: Consuming with lock from queue ${queue} with lockTimeout: ${lockTimeout}ms`);
|
|
581
570
|
}
|
|
582
|
-
const channel = await this.getNewChannel({
|
|
571
|
+
const channel = await this.getNewChannel({});
|
|
583
572
|
return channel.addSetup(async (confirmChannel: ConfirmChannel) => {
|
|
584
|
-
const q = await this.assertQueue(queue,
|
|
573
|
+
const q = await this.assertQueue(queue, optionsWithDefaults);
|
|
585
574
|
await confirmChannel.prefetch(limit, false);
|
|
586
575
|
const { consumerTag } = await confirmChannel.consume(
|
|
587
576
|
queue,
|
|
@@ -669,19 +658,19 @@ class RabbitMq implements IAfRabbitMq {
|
|
|
669
658
|
});
|
|
670
659
|
}
|
|
671
660
|
|
|
672
|
-
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> {
|
|
673
662
|
const optionsWithDefaults = { ...DEFAULT_OPTIONS, ...options };
|
|
674
663
|
RabbitMq.validateName('exchange', exchange);
|
|
675
664
|
RabbitMq.validateName('queue', queue);
|
|
676
665
|
const { limit, deadMessageTtl } = optionsWithDefaults;
|
|
677
666
|
await this.saveConsumer(queue, callback, options);
|
|
678
|
-
const channel: ChannelWrapper = await this.getNewChannel({ name: `consume
|
|
667
|
+
const channel: ChannelWrapper = await this.getNewChannel({ name: `consume-exchange-${exchange}-queue-${queue}` });
|
|
679
668
|
|
|
680
669
|
return channel.addSetup(async (c: ConfirmChannel) => {
|
|
681
670
|
const assertExchange = await assertExchangeFanout(c, exchange);
|
|
682
671
|
await c.assertQueue(queue);
|
|
683
672
|
this.exchanges[exchange] = assertExchange;
|
|
684
|
-
await c.prefetch(limit,
|
|
673
|
+
await c.prefetch(limit, false);
|
|
685
674
|
return Promise.all([
|
|
686
675
|
c.bindQueue(queue, exchange, ''),
|
|
687
676
|
this.consume(
|
|
@@ -693,11 +682,11 @@ class RabbitMq implements IAfRabbitMq {
|
|
|
693
682
|
});
|
|
694
683
|
}
|
|
695
684
|
|
|
696
|
-
async publish(exchange: string, content: any, customHeaders?: any): Promise<boolean> {
|
|
685
|
+
async publish(exchange: string, content: any, customHeaders?: any) : Promise<boolean> {
|
|
697
686
|
return wrapSetImmediate(async () => {
|
|
698
687
|
RabbitMq.validateName('exchange', exchange);
|
|
699
|
-
const channel: ChannelWrapper = await this.assertChannel(
|
|
700
|
-
await this.assertExchange(exchange
|
|
688
|
+
const channel: ChannelWrapper = await this.assertChannel();
|
|
689
|
+
await this.assertExchange(exchange);
|
|
701
690
|
await channel.publish(exchange, '',
|
|
702
691
|
Buffer.from(JSON.stringify(content)),
|
|
703
692
|
RabbitMq.getPublishOptions(customHeaders));
|
|
@@ -711,7 +700,7 @@ class RabbitMq implements IAfRabbitMq {
|
|
|
711
700
|
customHeaders?: any,
|
|
712
701
|
): Promise<boolean | undefined> {
|
|
713
702
|
try {
|
|
714
|
-
await this.assertChannel(
|
|
703
|
+
await this.assertChannel();
|
|
715
704
|
} catch (e) {
|
|
716
705
|
logger.error(`rabbit sendToQueue: failed to send assert channel when sending to queue ${queue}`, { e });
|
|
717
706
|
throw e;
|
|
@@ -719,7 +708,7 @@ class RabbitMq implements IAfRabbitMq {
|
|
|
719
708
|
|
|
720
709
|
try {
|
|
721
710
|
RabbitMq.validateName('queue', queue);
|
|
722
|
-
await this.assertQueue(queue,
|
|
711
|
+
await this.assertQueue(queue, options);
|
|
723
712
|
} catch (e) {
|
|
724
713
|
logger.error(`rabbit sendToQueue: failed to assert queue ${queue}`, { e });
|
|
725
714
|
throw e;
|
|
@@ -732,41 +721,34 @@ class RabbitMq implements IAfRabbitMq {
|
|
|
732
721
|
debug(`rabbit: sending to queue ${queue}`, { res });
|
|
733
722
|
return res;
|
|
734
723
|
} catch (e) {
|
|
735
|
-
|
|
724
|
+
const isConnected = await this.isConnected();
|
|
725
|
+
logger.error(`rabbit sendToQueue: failed to send to queue ${queue}, isConnected: ${isConnected}`, { e });
|
|
736
726
|
throw e;
|
|
737
727
|
}
|
|
738
728
|
}
|
|
739
729
|
|
|
740
|
-
async isConnected(): Promise<boolean> {
|
|
741
|
-
const
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
logger.error('rabbit: isConnected - false');
|
|
760
|
-
return false;
|
|
761
|
-
}
|
|
762
|
-
logger.info('rabbit: isConnected - true');
|
|
763
|
-
return true;
|
|
764
|
-
}),
|
|
765
|
-
);
|
|
766
|
-
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;
|
|
767
749
|
}
|
|
768
750
|
|
|
769
|
-
async gracefulShutdown(signal: string): Promise<void> {
|
|
751
|
+
async gracefulShutdown(signal: string) : Promise<void> {
|
|
770
752
|
const tagsNumber = this.consumersTags.length;
|
|
771
753
|
logger.info(`rabbit: [gracefully-shutdown] received ${signal}! canceling #${tagsNumber} tags...`);
|
|
772
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
|
-
};
|