@autofleet/rabbit 3.2.24-beta.4 → 3.2.24-beta.6

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