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