@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 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,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.connectionsMap = {
123
- [consts_1.ConnectionPurpose.Consume]: { connection: null, creatingConnection: false },
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(connectionPurpose) {
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.connectionsMap[connectionPurpose].creatingConnection = true;
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 newConnection = await (0, amqp_connection_manager_1.connect)(defaultUrls, {
181
+ const connection = await (0, amqp_connection_manager_1.connect)(defaultUrls, {
185
182
  findServers,
186
183
  });
187
- this.connectionsMap[connectionPurpose].connection = newConnection;
188
- newConnection.on('error', (err) => {
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
- newConnection.on('connectFailed', (err) => {
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
- newConnection.on('disconnect', ({ err }) => {
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
- newConnection.once('connect', async () => {
217
- this.connectionsMap[connectionPurpose].creatingConnection = false;
218
- this.em.emit(consts_1.CONNECTION_CREATED_CONST, 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);
219
218
  isResolved = true;
220
- resolve(newConnection);
219
+ resolve(connection);
221
220
  });
222
221
  });
223
222
  }
224
- 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 = {} } = {}) {
225
224
  let connection;
226
225
  try {
227
- connection = await this.getConnection(connectionPurpose);
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, connectionPurpose = consts_1.ConnectionPurpose.Consume }) {
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({ connectionPurpose });
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 = { connectionPurpose: consts_1.ConnectionPurpose.Consume }) {
274
- const channel = await this.assertChannel({ connectionPurpose: options.connectionPurpose });
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, connectionPurpose = consts_1.ConnectionPurpose.Consume) {
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, connectionPurpose) {
290
+ async deleteQueue(queue) {
297
291
  RabbitMq.validateName('queue', queue);
298
- const channel = await this.assertChannel({ connectionPurpose });
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, connectionPurpose) {
305
- const channel = await this.assertChannel({ connectionPurpose });
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, connectionPurpose, options) {
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({ connectionPurpose });
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, connectionPurpose });
333
- await this.deleteQueue(queueName, connectionPurpose);
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, connectionPurpose, options) {
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, connectionPurpose, options);
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({ connectionPurpose: consts_1.ConnectionPurpose.Consume });
403
+ const channel = await this.getNewChannel({});
410
404
  return channel.addSetup(async (confirmChannel) => {
411
- const q = await this.assertQueue(queue, consts_1.ConnectionPurpose.Consume, optionsWithDefaults);
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 - exchange - ${exchange} -queue - ${queue}` });
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, true);
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({ connectionPurpose: consts_1.ConnectionPurpose.Publish });
509
- await this.assertExchange(exchange, { connectionPurpose: consts_1.ConnectionPurpose.Publish });
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({ connectionPurpose: consts_1.ConnectionPurpose.Publish });
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, consts_1.ConnectionPurpose.Publish, options);
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
- 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 });
536
531
  throw e;
537
532
  }
538
533
  }
539
534
  async isConnected() {
540
- const isEachConnectionConnected = await Promise.all(Object.entries(this.connectionsMap).map(async ([connectionPurpose, connectionData]) => {
541
- const { connection } = connectionData;
542
- if (connectionPurpose === consts_1.ConnectionPurpose.Publish && !connection) {
543
- return true; // The connection hasn't been initialized yet, as no messages have been sent through it
544
- }
545
- const isConnected = connection?.isConnected();
546
- if (!isConnected) {
547
- logger_1.default.error('rabbit: isConnected - false');
548
- return false;
549
- }
550
- const channel = await this.assertChannel({ connectionPurpose: connectionPurpose });
551
- try {
552
- await Promise.all([
553
- channel.waitForConnect(),
554
- ...this.consumers.map((c) => channel.checkQueue(c.queue)),
555
- ]);
556
- }
557
- catch (e) {
558
- logger_1.default.error('rabbit: isConnected - false');
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;
@@ -17,7 +17,3 @@ export declare const DEFAULT_OPTIONS: {
17
17
  auditContext: null;
18
18
  enableRabbitTrace: boolean;
19
19
  };
20
- export declare enum ConnectionPurpose {
21
- Consume = "consume",
22
- Publish = "publish"
23
- }
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.ConnectionPurpose = 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;
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 = {}));
@@ -1,4 +1,3 @@
1
- import { AmqpConnectionManager } from 'amqp-connection-manager';
2
1
  import { ConsumeMessage, Options, Replies } from 'amqplib';
3
2
  export interface ExchangesCache {
4
3
  [key: string]: any;
@@ -42,7 +41,3 @@ export type AfConsumer = {
42
41
  options: ConsumeOptions | undefined;
43
42
  };
44
43
  export declare const CONSUMER_DEFAULT_OPTIONS: Options.Consume;
45
- export type ConnectionData = {
46
- connection: AmqpConnectionManager | null;
47
- creatingConnection: boolean;
48
- };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@autofleet/rabbit",
3
- "version": "3.2.24-beta.0",
3
+ "version": "3.2.24-beta.10",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "engines": {
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
- connectionsMap: {
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.connectionsMap = {
186
- [ConnectionPurpose.Consume]: { connection: null, creatingConnection: false },
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(connectionPurpose: ConnectionPurpose) {
287
- return new Promise<AmqpConnectionManager | undefined | null>(async (resolve, reject) => {
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.connectionsMap[connectionPurpose].creatingConnection = true;
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 newConnection: AmqpConnectionManager = await connect(defaultUrls, {
320
+ const connection: AmqpConnectionManager = await connect(defaultUrls, {
328
321
  findServers,
329
322
  });
330
323
 
331
- this.connectionsMap[connectionPurpose].connection = newConnection;
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
- newConnection.on('connectFailed', (err) => {
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
- newConnection.on('disconnect', ({ err }) => {
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
- newConnection.once('connect', async () => {
363
- this.connectionsMap[connectionPurpose].creatingConnection = false;
364
- this.em.emit(CONNECTION_CREATED_CONST, 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);
365
360
  isResolved = true;
366
- resolve(newConnection);
361
+ resolve(connection);
367
362
  });
368
363
  });
369
364
  }
370
365
 
371
- async getNewChannel({
372
- name = rand().toString(), onClose = null, options = {}, connectionPurpose = ConnectionPurpose.Consume,
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(connectionPurpose);
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, connectionPurpose = ConnectionPurpose.Consume }: assertChannelOpts): Promise<ChannelWrapper> {
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({ connectionPurpose });
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: any = { connectionPurpose: ConnectionPurpose.Consume }) {
423
- const channel: ChannelWrapper = await this.assertChannel({ connectionPurpose: options.connectionPurpose });
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, connectionPurpose: ConnectionPurpose = ConnectionPurpose.Consume): Promise<Replies.AssertQueue> {
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, connectionPurpose: ConnectionPurpose) {
438
+ private async deleteQueue(queue: string) {
450
439
  RabbitMq.validateName('queue', queue);
451
- const channel: ChannelWrapper = await this.assertChannel({ connectionPurpose });
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, connectionPurpose: ConnectionPurpose) {
459
- const channel: ChannelWrapper = await this.assertChannel({ connectionPurpose });
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, connectionPurpose: ConnectionPurpose, options?: Options.AssertQueue): Promise<Replies.AssertQueue> {
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({ connectionPurpose });
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, connectionPurpose });
487
- await this.deleteQueue(queueName, connectionPurpose);
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, connectionPurpose: ConnectionPurpose, options?: Options.AssertQueue) {
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, connectionPurpose, options);
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: boolean = this.consumers.some((consumer) => consumer.queue === queue);
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({ connectionPurpose: ConnectionPurpose.Consume });
571
+ const channel = await this.getNewChannel({});
583
572
  return channel.addSetup(async (confirmChannel: ConfirmChannel) => {
584
- const q = await this.assertQueue(queue, ConnectionPurpose.Consume, optionsWithDefaults);
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 - exchange - ${exchange} -queue - ${queue}` });
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, true);
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({ connectionPurpose: ConnectionPurpose.Publish });
700
- await this.assertExchange(exchange, { connectionPurpose: ConnectionPurpose.Publish });
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({ connectionPurpose: ConnectionPurpose.Publish });
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, ConnectionPurpose.Publish, options);
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
- 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 });
736
726
  throw e;
737
727
  }
738
728
  }
739
729
 
740
- async isConnected(): Promise<boolean> {
741
- const isEachConnectionConnected = await Promise.all(
742
- Object.entries(this.connectionsMap).map(async ([connectionPurpose, connectionData]) => {
743
- const { connection } = connectionData;
744
- if (connectionPurpose === ConnectionPurpose.Publish && !connection) {
745
- return true; // The connection hasn't been initialized yet, as no messages have been sent through it
746
- }
747
- const isConnected = connection?.isConnected();
748
- if (!isConnected) {
749
- logger.error('rabbit: isConnected - false');
750
- return false;
751
- }
752
- const channel: any = await this.assertChannel({ connectionPurpose: connectionPurpose as ConnectionPurpose });
753
- try {
754
- await Promise.all([
755
- channel.waitForConnect(),
756
- ...this.consumers.map((c: AfConsumer) => channel.checkQueue(c.queue)),
757
- ]);
758
- } catch (e) {
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
@@ -17,8 +17,3 @@ export const DEFAULT_OPTIONS = {
17
17
  auditContext: null,
18
18
  enableRabbitTrace: false,
19
19
  };
20
-
21
- export enum ConnectionPurpose {
22
- Consume = 'consume',
23
- Publish = 'publish',
24
- }
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
- };