@autofleet/rabbit 3.2.21-beta.1 → 3.2.22-beta.0

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
@@ -1,9 +1,9 @@
1
1
  /// <reference types="node" />
2
2
  import { EventEmitter } from 'events';
3
- import { AmqpConnectionManager, ChannelWrapper } from 'amqp-connection-manager';
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 { CallbackFunction, ConsumeMessageOrNull, ConsumeOptions, CustomMessageHeaders, QueuesCache, RedisLockType, ExchangesCache, QueueSetupPromisesDictionary, assertChannelOpts, newChannelOpts, PublishOptions } from './lib/types';
6
+ import { CallbackFunction, ConsumeMessageOrNull, ConsumeOptions, CustomMessageHeaders, QueuesCache, RedisLockType, ExchangesCache, QueueSetupPromisesDictionary, ConnectionPurpose, ConnectionData } from './lib/types';
7
7
  export interface IAfRabbitMq {
8
8
  ack: any;
9
9
  nack: any;
@@ -33,6 +33,17 @@ export interface AfRabbitOptions {
33
33
  dontRetryAssert?: boolean;
34
34
  rabbitHost?: string;
35
35
  }
36
+ type newChannelOpts = {
37
+ name?: string;
38
+ onClose?: null | ((args: any | null) => void);
39
+ options?: CreateChannelOpts | undefined;
40
+ connectionPurpose: ConnectionPurpose;
41
+ };
42
+ type assertChannelOpts = {
43
+ channelName?: string;
44
+ force?: boolean;
45
+ connectionPurpose: ConnectionPurpose;
46
+ };
36
47
  declare class RabbitMq implements IAfRabbitMq {
37
48
  static parseMsg(msg: any): any;
38
49
  static validateName(type: string, name: string): void;
@@ -51,9 +62,11 @@ declare class RabbitMq implements IAfRabbitMq {
51
62
  channel: ChannelWrapper | null;
52
63
  publishChannelSetupPromise: Promise<ChannelWrapper> | null;
53
64
  blockReconnect: boolean | null | undefined;
54
- connection: AmqpConnectionManager | null | undefined;
65
+ connectionsMap: {
66
+ [ConnectionPurpose.Consume]: ConnectionData;
67
+ [ConnectionPurpose.Publish]: ConnectionData;
68
+ };
55
69
  em: EventEmitter;
56
- creatingConnection: boolean;
57
70
  exchanges: ExchangesCache;
58
71
  queues: QueuesCache;
59
72
  queueSetupPromises: QueueSetupPromisesDictionary;
@@ -67,24 +80,24 @@ declare class RabbitMq implements IAfRabbitMq {
67
80
  private shouldConsumeMessageByTimestamp;
68
81
  ack: (channel: ConfirmChannel, msg: ConsumeMessageOrNull, shouldUpdateRedisTimestamp?: boolean, releaseLock?: null) => (userMsg: ConsumeMessage) => Promise<any>;
69
82
  nack: (channel: ConfirmChannel, queue: string, options: any, deadQueueOptions: Options.AssertQueue, msg: ConsumeMessageOrNull, releaseLock: any) => (userMsg: ConsumeMessageOrNull, { skipRetry, }?: NackOptions) => Promise<any>;
70
- getConnection(): Promise<AmqpConnectionManager>;
71
- getNewChannel({ name, onClose, options }?: newChannelOpts): Promise<ChannelWrapper>;
72
- assertChannel({ force, newChannelOptions }?: assertChannelOpts): Promise<ChannelWrapper>;
73
- assertExchange(exchangeName: string): Promise<any>;
74
- getQueueLength(queue: string): Promise<Replies.AssertQueue>;
83
+ getConnection(connectionPurpose: ConnectionPurpose): Promise<AmqpConnectionManager | null | undefined>;
84
+ getNewChannel({ name, onClose, options, connectionPurpose, }: newChannelOpts): Promise<ChannelWrapper>;
85
+ assertChannel({ force, connectionPurpose }: assertChannelOpts): Promise<ChannelWrapper>;
86
+ assertExchange(exchangeName: string, options?: any): Promise<any>;
87
+ getQueueLength(queue: string, connectionPurpose?: ConnectionPurpose): Promise<Replies.AssertQueue>;
75
88
  private deleteQueue;
76
- bindQueue(queue: string, exchange: string): Promise<void>;
77
- setupQueue(queueName: string, options?: Options.AssertQueue): Promise<Replies.AssertQueue>;
78
- assertQueue(queueName: string, options?: Options.AssertQueue): Promise<any>;
89
+ bindQueue(queue: string, exchange: string, connectionPurpose: ConnectionPurpose): Promise<void>;
90
+ setupQueue(queueName: string, connectionPurpose: ConnectionPurpose, options?: Options.AssertQueue): Promise<Replies.AssertQueue>;
91
+ assertQueue(queueName: string, connectionPurpose: ConnectionPurpose, options?: Options.AssertQueue): Promise<any>;
79
92
  private saveConsumer;
80
93
  consume(queue: string, callback: CallbackFunction, options?: ConsumeOptions): Promise<any>;
81
94
  private lockRedisIfNeeded;
82
95
  private unlockRedisIfNeeded;
83
96
  private consumeFromRabbit;
84
97
  consumeFromExchange(queue: string, exchange: string, callback: CallbackFunction, options?: ConsumeOptions): Promise<any>;
85
- publish(exchange: string, content: any, customHeaders?: any, options?: PublishOptions): Promise<boolean>;
98
+ publish(exchange: string, content: any, customHeaders?: any): Promise<boolean>;
86
99
  sendToQueue(queue: string, content: any, options?: any, customHeaders?: any): Promise<boolean | undefined>;
87
- isConnected(): Promise<boolean>;
100
+ isConnected(connectionPurpose: ConnectionPurpose): Promise<boolean>;
88
101
  gracefulShutdown(signal: string): Promise<void>;
89
102
  }
90
103
  export default RabbitMq;
package/dist/index.js CHANGED
@@ -6,7 +6,6 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
6
6
  Object.defineProperty(exports, "__esModule", { value: true });
7
7
  const events_1 = require("events");
8
8
  const util_1 = require("util");
9
- const lodash_1 = require("lodash");
10
9
  const moment_1 = __importDefault(require("moment"));
11
10
  const redis_lock_1 = __importDefault(require("redis-lock"));
12
11
  const amqp_connection_manager_1 = require("amqp-connection-manager");
@@ -119,8 +118,10 @@ class RabbitMq {
119
118
  this.em = new events_1.EventEmitter();
120
119
  this.channel = null;
121
120
  this.publishChannelSetupPromise = null;
122
- this.connection = null;
123
- this.creatingConnection = false;
121
+ this.connectionsMap = {
122
+ [types_1.ConnectionPurpose.Consume]: { connection: null, creatingConnection: false },
123
+ [types_1.ConnectionPurpose.Publish]: { connection: null, creatingConnection: false },
124
+ };
124
125
  this.exchanges = {};
125
126
  this.queues = {};
126
127
  this.queueSetupPromises = {};
@@ -141,30 +142,31 @@ class RabbitMq {
141
142
  });
142
143
  }
143
144
  }
144
- async getConnection() {
145
+ async getConnection(connectionPurpose) {
145
146
  return new Promise(async (resolve, reject) => {
147
+ const { connection, creatingConnection } = this.connectionsMap[connectionPurpose];
146
148
  if (this.blockReconnect) {
147
149
  debug('rabbit: block reconnect');
148
150
  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
149
151
  // @ts-ignore
150
152
  return resolve();
151
153
  }
152
- if (this.connection !== null) {
153
- if (this.options?.disableReconnect || this.connection?.isConnected()) {
154
+ if (connection !== null) {
155
+ if (this.options?.disableReconnect || connection?.isConnected()) {
154
156
  debug('rabbit: connection - is connected');
155
157
  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
156
158
  // @ts-ignore
157
- return resolve(this.connection);
159
+ return resolve(connection);
158
160
  }
159
161
  debug('rabbit: connection - reconnecting');
160
162
  }
161
- if (this.creatingConnection) {
163
+ if (creatingConnection) {
162
164
  debug('rabbit: creating connection emi');
163
165
  this.em.once(consts_1.CONNECTION_CREATED_CONST, resolve);
164
166
  this.em.once(consts_1.CONNECTION_FAILED_CONST, reject);
165
167
  return;
166
168
  }
167
- this.creatingConnection = true;
169
+ this.connectionsMap[connectionPurpose].creatingConnection = true;
168
170
  let isResolved = false;
169
171
  // It is import to use it as a function and not as a variable
170
172
  // because of k8s changes the env variables
@@ -177,11 +179,15 @@ class RabbitMq {
177
179
  return [`amqp://${userName}:${password}@${host}?heartbeat=${HEARTBEAT}`];
178
180
  };
179
181
  const defaultUrls = findServers();
180
- const connection = await (0, amqp_connection_manager_1.connect)(defaultUrls, {
182
+ const newConnection = await (0, amqp_connection_manager_1.connect)(defaultUrls, {
181
183
  findServers,
182
184
  });
183
- this.connection = connection;
184
- this.connection.on('error', (err) => {
185
+ if (!newConnection) {
186
+ logger_1.default.error('rabbit: couldnt create a connection');
187
+ return resolve(connection);
188
+ }
189
+ this.connectionsMap[connectionPurpose].connection = newConnection;
190
+ newConnection.on('error', (err) => {
185
191
  logger_1.default.error('rabbit: connection error', { err });
186
192
  if (!isResolved) {
187
193
  isResolved = true;
@@ -189,7 +195,7 @@ class RabbitMq {
189
195
  this.em.emit(consts_1.CONNECTION_FAILED_CONST, err);
190
196
  }
191
197
  });
192
- this.connection.on('connectFailed', (err) => {
198
+ newConnection.on('connectFailed', (err) => {
193
199
  this.consumersTags = [];
194
200
  logger_1.default.error('rabbit: connection connectFailed', { err });
195
201
  if (!isResolved) {
@@ -198,8 +204,7 @@ class RabbitMq {
198
204
  this.em.emit(consts_1.CONNECTION_FAILED_CONST, err);
199
205
  }
200
206
  });
201
- this.connection.on('disconnect', ({ err }) => {
202
- // this.channel = null;
207
+ newConnection.on('disconnect', ({ err }) => {
203
208
  this.consumersTags = [];
204
209
  debug('rabbit: connection closed');
205
210
  if (this.options?.disableReconnect) {
@@ -210,24 +215,27 @@ class RabbitMq {
210
215
  logger_1.default.error(`${this.RECONNECT_MSG}${err && ` - ${err}`}`);
211
216
  }
212
217
  });
213
- this.connection.once('connect', async () => {
218
+ newConnection.once('connect', async () => {
214
219
  debug('rabbit: connection established');
215
- this.creatingConnection = false;
216
- this.em.emit(consts_1.CONNECTION_CREATED_CONST, connection);
220
+ this.connectionsMap[connectionPurpose].creatingConnection = false;
221
+ this.em.emit(consts_1.CONNECTION_CREATED_CONST, newConnection);
217
222
  isResolved = true;
218
- resolve(connection);
223
+ resolve(newConnection);
219
224
  });
220
225
  });
221
226
  }
222
- async getNewChannel({ name = (0, utils_1.rand)().toString(), onClose = null, options = {} } = {}) {
227
+ async getNewChannel({ name = (0, utils_1.rand)().toString(), onClose = null, options = {}, connectionPurpose = types_1.ConnectionPurpose.Consume, }) {
223
228
  let connection;
224
229
  try {
225
- connection = await this.getConnection();
230
+ connection = await this.getConnection(connectionPurpose);
226
231
  }
227
232
  catch (e) {
228
233
  logger_1.default.error(`rabbit: error on get connection for new channel ${name} `, { e });
229
234
  throw e;
230
235
  }
236
+ if (!connection) {
237
+ throw new Error(`rabbit: couldnt get connection for new channel ${name}`);
238
+ }
231
239
  const channel = connection.createChannel({ ...options });
232
240
  (0, events_1.once)(channel, 'close').then((args) => {
233
241
  logger_1.default.error(`rabbit: channel ${name} closed`);
@@ -243,14 +251,14 @@ class RabbitMq {
243
251
  throw err;
244
252
  }
245
253
  }
246
- async assertChannel({ force = false, newChannelOptions = {} } = {}) {
254
+ async assertChannel({ force = false, connectionPurpose = types_1.ConnectionPurpose.Consume }) {
247
255
  if (!this.publishChannelSetupPromise) {
248
256
  this.publishChannelSetupPromise = new Promise(async (resolve, reject) => {
249
257
  if (this.channel && !force) {
250
258
  return resolve(this.channel);
251
259
  }
252
260
  try {
253
- const channel = await this.getNewChannel({ options: newChannelOptions });
261
+ const channel = await this.getNewChannel({ connectionPurpose });
254
262
  channel.on('error', (err) => {
255
263
  logger_1.default.error('rabbit: channel error', { err });
256
264
  });
@@ -264,8 +272,8 @@ class RabbitMq {
264
272
  }
265
273
  return this.publishChannelSetupPromise;
266
274
  }
267
- async assertExchange(exchangeName) {
268
- const channel = await this.assertChannel();
275
+ async assertExchange(exchangeName, options) {
276
+ const channel = await this.assertChannel({ connectionPurpose: options.connectionPurpose });
269
277
  if (this.exchanges[exchangeName]) {
270
278
  return this.exchanges[exchangeName];
271
279
  }
@@ -273,32 +281,33 @@ class RabbitMq {
273
281
  this.exchanges[exchangeName] = exchange;
274
282
  return exchange;
275
283
  }
276
- async getQueueLength(queue) {
284
+ async getQueueLength(queue, connectionPurpose = types_1.ConnectionPurpose.Consume) {
277
285
  RabbitMq.validateName('queue', queue);
286
+ const { connection } = this.connectionsMap[connectionPurpose];
278
287
  const { channel } = this;
279
288
  if (!channel) {
280
289
  throw new Error('channel is not defined');
281
290
  }
282
- debug('rabbit: getting queue length', { queue, connected: this.connection?.isConnected() });
291
+ debug('rabbit: getting queue length', { queue, connected: connection?.isConnected() });
283
292
  return channel?.checkQueue(queue);
284
293
  }
285
- async deleteQueue(queue) {
294
+ async deleteQueue(queue, connectionPurpose) {
286
295
  RabbitMq.validateName('queue', queue);
287
- const channel = await this.assertChannel();
296
+ const channel = await this.assertChannel({ connectionPurpose });
288
297
  logger_1.default.info('rabbit: deleting queue', { queue });
289
298
  const deleteQueueRes = await channel.deleteQueue(queue);
290
299
  debug('queue deleted', deleteQueueRes);
291
300
  return deleteQueueRes;
292
301
  }
293
- async bindQueue(queue, exchange) {
294
- const channel = await this.assertChannel();
302
+ async bindQueue(queue, exchange, connectionPurpose) {
303
+ const channel = await this.assertChannel({ connectionPurpose });
295
304
  await channel.addSetup((setupChannel) => setupChannel.bindQueue(queue, exchange, ''));
296
305
  return channel.bindQueue(queue, exchange, '');
297
306
  }
298
- async setupQueue(queueName, options) {
307
+ async setupQueue(queueName, connectionPurpose, options) {
299
308
  let queue;
300
309
  try {
301
- const channel = await this.assertChannel();
310
+ const channel = await this.assertChannel({ connectionPurpose });
302
311
  debug('assertQueue->channel.addSetup', { queueName });
303
312
  await channel.addSetup((setupChannel) => setupChannel.assertQueue(queueName, options));
304
313
  debug('assertQueue->channel.assertQueue', { queueName });
@@ -308,8 +317,8 @@ class RabbitMq {
308
317
  logger_1.default.error('rabbit: assertQueue error', { queueName, options, error: e });
309
318
  if (!this.options?.dontRetryAssert) {
310
319
  debug('retrying assertQueue', { queueName });
311
- const channel = await this.assertChannel({ force: true });
312
- await this.deleteQueue(queueName);
320
+ const channel = await this.assertChannel({ force: true, connectionPurpose });
321
+ await this.deleteQueue(queueName, connectionPurpose);
313
322
  debug('retrying assertQueue->channel.addSetup', { queueName });
314
323
  await channel.addSetup((setupChannel) => setupChannel.assertQueue(queueName, options));
315
324
  debug('retrying assertQueue->channel.assertQueue', { queueName });
@@ -322,7 +331,7 @@ class RabbitMq {
322
331
  this.queues[queueName] = queueName;
323
332
  return queue;
324
333
  }
325
- async assertQueue(queueName, options) {
334
+ async assertQueue(queueName, connectionPurpose, options) {
326
335
  RabbitMq.validateName('queue', queueName);
327
336
  if (this.queues[queueName]) {
328
337
  delete this.queueSetupPromises[queueName];
@@ -331,7 +340,7 @@ class RabbitMq {
331
340
  if (this.queueSetupPromises[queueName]) {
332
341
  return this.queueSetupPromises[queueName];
333
342
  }
334
- this.queueSetupPromises[queueName] = this.setupQueue(queueName, options);
343
+ this.queueSetupPromises[queueName] = this.setupQueue(queueName, connectionPurpose, options);
335
344
  return this.queueSetupPromises[queueName];
336
345
  }
337
346
  saveConsumer(queue, callback, options) {
@@ -374,11 +383,10 @@ class RabbitMq {
374
383
  }
375
384
  logger_1.default.info(`rabbit: Consuming with lock from queue ${queue} with lockTimeout: ${lockTimeout}ms`);
376
385
  }
377
- const channel = await this.getNewChannel({});
386
+ const channel = await this.getNewChannel({ connectionPurpose: types_1.ConnectionPurpose.Consume });
378
387
  return channel.addSetup(async (confirmChannel) => {
379
388
  await confirmChannel.assertQueue(queue, options ? { messageTtl: options.messageTtl } : undefined);
380
389
  await confirmChannel.prefetch(limit, true);
381
- const channelConsumerOptions = optionsWithDefaults.channelConsumeOptions ? (0, lodash_1.merge)(types_1.CONSUMER_DEFAULT_OPTIONS, optionsWithDefaults.channelConsumeOptions) : types_1.CONSUMER_DEFAULT_OPTIONS;
382
390
  const { consumerTag } = await confirmChannel.consume(queue, async (msg) => {
383
391
  if (!msg) {
384
392
  return null;
@@ -439,7 +447,7 @@ class RabbitMq {
439
447
  catch (e) {
440
448
  await localNack(msg);
441
449
  }
442
- }, channelConsumerOptions);
450
+ }, types_1.CONSUMER_DEFAULT_OPTIONS);
443
451
  if (!consumerTag) {
444
452
  logger_1.default.error(`rabbit: failed to consume from queue ${queue}`);
445
453
  }
@@ -455,7 +463,7 @@ class RabbitMq {
455
463
  RabbitMq.validateName('queue', queue);
456
464
  const { limit, deadMessageTtl } = optionsWithDefaults;
457
465
  await this.saveConsumer(queue, callback, options);
458
- const channel = await this.getNewChannel({ name: `consume-exchange-${exchange}-queue-${queue}` });
466
+ const channel = await this.getNewChannel({ name: `consume - exchange - ${exchange} -queue - ${queue}`, connectionPurpose: types_1.ConnectionPurpose.Consume });
459
467
  return channel.addSetup(async (c) => {
460
468
  const assertExchange = await (0, utils_1.assertExchangeFanout)(c, exchange);
461
469
  await c.assertQueue(queue);
@@ -467,17 +475,17 @@ class RabbitMq {
467
475
  ]);
468
476
  });
469
477
  }
470
- async publish(exchange, content, customHeaders, options) {
478
+ async publish(exchange, content, customHeaders) {
471
479
  return (0, utils_1.wrapSetImmediate)(async () => {
472
480
  RabbitMq.validateName('exchange', exchange);
473
- const channel = await this.assertChannel({ newChannelOptions: options?.newChannelOptions });
474
- await this.assertExchange(exchange);
481
+ const channel = await this.assertChannel({ connectionPurpose: types_1.ConnectionPurpose.Publish });
482
+ await this.assertExchange(exchange, { connectionPurpose: types_1.ConnectionPurpose.Publish });
475
483
  await channel.publish(exchange, '', Buffer.from(JSON.stringify(content)), RabbitMq.getPublishOptions(customHeaders));
476
484
  });
477
485
  }
478
486
  async sendToQueue(queue, content, options, customHeaders) {
479
487
  try {
480
- await this.assertChannel({ newChannelOptions: options?.newChannelOptions });
488
+ await this.assertChannel({ connectionPurpose: types_1.ConnectionPurpose.Publish });
481
489
  }
482
490
  catch (e) {
483
491
  logger_1.default.error(`rabbit sendToQueue: failed to send assert channel when sending to queue ${queue}`, { e });
@@ -485,7 +493,7 @@ class RabbitMq {
485
493
  }
486
494
  try {
487
495
  RabbitMq.validateName('queue', queue);
488
- await this.assertQueue(queue, options);
496
+ await this.assertQueue(queue, types_1.ConnectionPurpose.Publish, options);
489
497
  }
490
498
  catch (e) {
491
499
  logger_1.default.error(`rabbit sendToQueue: failed to assert queue ${queue}`, { e });
@@ -497,19 +505,23 @@ class RabbitMq {
497
505
  return res;
498
506
  }
499
507
  catch (e) {
500
- const isConnected = await this.isConnected();
508
+ const isConnected = await this.isConnected(types_1.ConnectionPurpose.Publish);
501
509
  logger_1.default.error(`rabbit sendToQueue: failed to send to queue ${queue}, isConnected: ${isConnected}`, { e });
502
510
  throw e;
503
511
  }
504
512
  }
505
- async isConnected() {
506
- const connection = await this.getConnection();
513
+ async isConnected(connectionPurpose) {
514
+ const connection = await this.getConnection(connectionPurpose);
515
+ if (!connection) {
516
+ logger_1.default.error('rabbit: isConnected - false');
517
+ return false;
518
+ }
507
519
  const isConnected = connection.isConnected();
508
520
  if (!isConnected) {
509
521
  logger_1.default.error('rabbit: isConnected - false');
510
522
  return false;
511
523
  }
512
- const channel = await this.assertChannel();
524
+ const channel = await this.assertChannel({ connectionPurpose });
513
525
  try {
514
526
  await Promise.all([
515
527
  channel.waitForConnect(),
@@ -1,4 +1,4 @@
1
- import { CreateChannelOpts } from 'amqp-connection-manager';
1
+ import { AmqpConnectionManager } from 'amqp-connection-manager';
2
2
  import { ConsumeMessage, Options, Replies } from 'amqplib';
3
3
  export interface ExchangesCache {
4
4
  [key: string]: any;
@@ -23,25 +23,27 @@ export interface ConsumeOptions {
23
23
  useConsumeWithLock?: boolean;
24
24
  auditContext?: any;
25
25
  enableRabbitTrace?: boolean;
26
- channelConsumeOptions?: Options.Consume;
27
26
  }
28
27
  export type CallbackFunction = (msg: ConsumeMessage, ack: any, nack: any) => Promise<any>;
29
28
  export type newChannelOpts = {
30
29
  name?: string;
31
30
  onClose?: null | ((args: any | null) => void);
32
- options?: CreateChannelOpts | undefined;
33
31
  };
34
32
  export type assertChannelOpts = {
35
33
  channelName?: string;
36
34
  force?: boolean;
37
- newChannelOptions?: newChannelOpts;
38
35
  };
39
- export interface PublishOptions {
40
- newChannelOptions?: newChannelOpts;
41
- }
42
36
  export type AfConsumer = {
43
37
  queue: string;
44
38
  callback: CallbackFunction;
45
39
  options: ConsumeOptions | undefined;
46
40
  };
47
41
  export declare const CONSUMER_DEFAULT_OPTIONS: Options.Consume;
42
+ export type ConnectionData = {
43
+ connection: AmqpConnectionManager | null;
44
+ creatingConnection: boolean;
45
+ };
46
+ export declare enum ConnectionPurpose {
47
+ Consume = "consume",
48
+ Publish = "publish"
49
+ }
package/dist/lib/types.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.CONSUMER_DEFAULT_OPTIONS = void 0;
3
+ exports.ConnectionPurpose = exports.CONSUMER_DEFAULT_OPTIONS = void 0;
4
4
  const HA_PROMOTE_ON_FAILURE = 'ha-promote-on-failure';
5
5
  const HA_PROMOTE_ON_SHUTDOWN = 'ha-promote-on-shutdown';
6
6
  exports.CONSUMER_DEFAULT_OPTIONS = {
@@ -9,3 +9,8 @@ exports.CONSUMER_DEFAULT_OPTIONS = {
9
9
  [HA_PROMOTE_ON_SHUTDOWN]: 'always',
10
10
  },
11
11
  };
12
+ var ConnectionPurpose;
13
+ (function (ConnectionPurpose) {
14
+ ConnectionPurpose["Consume"] = "consume";
15
+ ConnectionPurpose["Publish"] = "publish";
16
+ })(ConnectionPurpose = exports.ConnectionPurpose || (exports.ConnectionPurpose = {}));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@autofleet/rabbit",
3
- "version": "3.2.21-beta.1",
3
+ "version": "3.2.22-beta.0",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "scripts": {
@@ -19,7 +19,6 @@
19
19
  "amqp-connection-manager": "4.1.9",
20
20
  "amqplib": "0.10.3",
21
21
  "bluebird": "^3.7.2",
22
- "lodash": "^4.17.21",
23
22
  "moment": "^2.29.1",
24
23
  "redis": "^3.1.2",
25
24
  "redis-lock": "^0.1.4"
@@ -31,7 +30,6 @@
31
30
  "@autofleet/logger": "4.0.6",
32
31
  "@types/amqplib": "0.8.2",
33
32
  "@types/jest": "^29.5.12",
34
- "@types/lodash": "^4.17.12",
35
33
  "@types/node": "^20.14.11",
36
34
  "@typescript-eslint/eslint-plugin": "^4.8.1",
37
35
  "eslint": "^7.13.0",
@@ -45,4 +43,4 @@
45
43
  },
46
44
  "author": "",
47
45
  "license": "ISC"
48
- }
46
+ }
package/src/index.ts CHANGED
@@ -2,11 +2,10 @@
2
2
 
3
3
  import { EventEmitter, once } from 'events';
4
4
  import { promisify } from 'util';
5
- import { merge } from 'lodash';
6
5
  import moment from 'moment';
7
6
  import RedisLock from 'redis-lock';
8
7
  import {
9
- AmqpConnectionManager, ChannelWrapper, connect,
8
+ AmqpConnectionManager, ChannelWrapper, connect, CreateChannelOpts,
10
9
  } from 'amqp-connection-manager';
11
10
  import {
12
11
  ConfirmChannel, ConsumeMessage, Options, Replies,
@@ -37,16 +36,14 @@ import {
37
36
  QueuesCache,
38
37
  RedisLockType,
39
38
  ExchangesCache, CONSUMER_DEFAULT_OPTIONS, QueueSetupPromisesDictionary,
40
- assertChannelOpts,
41
- newChannelOpts,
42
- PublishOptions,
39
+ ConnectionPurpose,
40
+ ConnectionData,
43
41
  } from './lib/types';
44
42
 
45
43
  // const debug = nodeDebug('af-rabbitmq')
46
44
  const debug = logger.debug.bind(logger);
47
45
 
48
46
  const PUBLISH_TIMEOUT = 1000 * 10;
49
-
50
47
  export interface IAfRabbitMq {
51
48
  ack: any;
52
49
  nack: any;
@@ -82,6 +79,19 @@ export interface AfRabbitOptions {
82
79
  rabbitHost?: string;
83
80
  }
84
81
 
82
+ type newChannelOpts = {
83
+ name?: string;
84
+ onClose?: null | ((args: any | null) => void);
85
+ options?: CreateChannelOpts | undefined;
86
+ connectionPurpose: ConnectionPurpose,
87
+ };
88
+
89
+ type assertChannelOpts = {
90
+ channelName?: string;
91
+ force?: boolean;
92
+ connectionPurpose: ConnectionPurpose;
93
+ }
94
+
85
95
  type AfConsumer = {
86
96
  queue: string;
87
97
  callback: CallbackFunction;
@@ -91,7 +101,7 @@ type AfConsumer = {
91
101
  const HEARTBEAT = '60';
92
102
 
93
103
  class RabbitMq implements IAfRabbitMq {
94
- static parseMsg(msg: any) : any {
104
+ static parseMsg(msg: any): any {
95
105
  let { content } = msg;
96
106
  content = content.toString();
97
107
 
@@ -136,14 +146,15 @@ class RabbitMq implements IAfRabbitMq {
136
146
 
137
147
  publishChannelSetupPromise: Promise<ChannelWrapper> | null;
138
148
 
139
- blockReconnect: boolean | null | undefined
149
+ blockReconnect: boolean | null | undefined;
140
150
 
141
- connection: AmqpConnectionManager | null | undefined
151
+ connectionsMap: {
152
+ [ConnectionPurpose.Consume]: ConnectionData;
153
+ [ConnectionPurpose.Publish]: ConnectionData;
154
+ };
142
155
 
143
156
  em: EventEmitter;
144
157
 
145
- creatingConnection: boolean;
146
-
147
158
  exchanges: ExchangesCache;
148
159
 
149
160
  queues: QueuesCache;
@@ -165,8 +176,10 @@ class RabbitMq implements IAfRabbitMq {
165
176
  this.em = new EventEmitter();
166
177
  this.channel = null;
167
178
  this.publishChannelSetupPromise = null;
168
- this.connection = null;
169
- this.creatingConnection = false;
179
+ this.connectionsMap = {
180
+ [ConnectionPurpose.Consume]: { connection: null, creatingConnection: false },
181
+ [ConnectionPurpose.Publish]: { connection: null, creatingConnection: false },
182
+ };
170
183
  this.exchanges = {};
171
184
  this.queues = {};
172
185
  this.queueSetupPromises = {};
@@ -202,7 +215,7 @@ class RabbitMq implements IAfRabbitMq {
202
215
  return false;
203
216
  }
204
217
 
205
- public ack = (channel: ConfirmChannel, msg: ConsumeMessageOrNull, shouldUpdateRedisTimestamp = false, releaseLock = null) => async (userMsg: ConsumeMessage) : Promise<any> => {
218
+ public ack = (channel: ConfirmChannel, msg: ConsumeMessageOrNull, shouldUpdateRedisTimestamp = false, releaseLock = null) => async (userMsg: ConsumeMessage): Promise<any> => {
206
219
  if (msg) {
207
220
  debug('rabbit acking message', { deliveryTag: msg.fields.deliveryTag });
208
221
  await channel.ack(msg);
@@ -228,8 +241,8 @@ class RabbitMq implements IAfRabbitMq {
228
241
  userMsg: ConsumeMessageOrNull,
229
242
  {
230
243
  skipRetry = false,
231
- }: NackOptions = { },
232
- ) : Promise<any> => {
244
+ }: NackOptions = {},
245
+ ): Promise<any> => {
233
246
  await this.unlockRedisIfNeeded(releaseLock);
234
247
  if (channel && msg) {
235
248
  if (
@@ -263,30 +276,31 @@ class RabbitMq implements IAfRabbitMq {
263
276
  }
264
277
  }
265
278
 
266
- async getConnection() {
267
- return new Promise<AmqpConnectionManager>(async (resolve, reject) => {
279
+ async getConnection(connectionPurpose: ConnectionPurpose) {
280
+ return new Promise<AmqpConnectionManager | undefined | null>(async (resolve, reject) => {
281
+ const { connection, creatingConnection } = this.connectionsMap[connectionPurpose];
268
282
  if (this.blockReconnect) {
269
283
  debug('rabbit: block reconnect');
270
284
  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
271
285
  // @ts-ignore
272
286
  return resolve();
273
287
  }
274
- if (this.connection !== null) {
275
- if (this.options?.disableReconnect || this.connection?.isConnected()) {
288
+ if (connection !== null) {
289
+ if (this.options?.disableReconnect || connection?.isConnected()) {
276
290
  debug('rabbit: connection - is connected');
277
291
  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
278
292
  // @ts-ignore
279
- return resolve(this.connection);
293
+ return resolve(connection);
280
294
  }
281
295
  debug('rabbit: connection - reconnecting');
282
296
  }
283
- if (this.creatingConnection) {
297
+ if (creatingConnection) {
284
298
  debug('rabbit: creating connection emi');
285
299
  this.em.once(CONNECTION_CREATED_CONST, resolve);
286
300
  this.em.once(CONNECTION_FAILED_CONST, reject);
287
301
  return;
288
302
  }
289
- this.creatingConnection = true;
303
+ this.connectionsMap[connectionPurpose].creatingConnection = true;
290
304
  let isResolved = false;
291
305
 
292
306
  // It is import to use it as a function and not as a variable
@@ -303,12 +317,18 @@ class RabbitMq implements IAfRabbitMq {
303
317
  };
304
318
 
305
319
  const defaultUrls = findServers();
306
- const connection: AmqpConnectionManager = await connect(defaultUrls, {
320
+ const newConnection: AmqpConnectionManager = await connect(defaultUrls, {
307
321
  findServers,
308
322
  });
309
323
 
310
- this.connection = connection;
311
- this.connection.on('error', (err) => {
324
+ if (!newConnection) {
325
+ logger.error('rabbit: couldnt create a connection');
326
+ return resolve(connection);
327
+ }
328
+
329
+ this.connectionsMap[connectionPurpose].connection = newConnection;
330
+
331
+ newConnection.on('error', (err) => {
312
332
  logger.error('rabbit: connection error', { err });
313
333
  if (!isResolved) {
314
334
  isResolved = true;
@@ -317,7 +337,7 @@ class RabbitMq implements IAfRabbitMq {
317
337
  }
318
338
  });
319
339
 
320
- this.connection.on('connectFailed', (err) => {
340
+ newConnection.on('connectFailed', (err) => {
321
341
  this.consumersTags = [];
322
342
  logger.error('rabbit: connection connectFailed', { err });
323
343
  if (!isResolved) {
@@ -327,8 +347,7 @@ class RabbitMq implements IAfRabbitMq {
327
347
  }
328
348
  });
329
349
 
330
- this.connection.on('disconnect', ({ err }) => {
331
- // this.channel = null;
350
+ newConnection.on('disconnect', ({ err }) => {
332
351
  this.consumersTags = [];
333
352
  debug('rabbit: connection closed');
334
353
  if (this.options?.disableReconnect) {
@@ -338,25 +357,29 @@ class RabbitMq implements IAfRabbitMq {
338
357
  logger.error(`${this.RECONNECT_MSG}${err && ` - ${err}`}`);
339
358
  }
340
359
  });
341
-
342
- this.connection.once('connect', async () => {
360
+ newConnection.once('connect', async () => {
343
361
  debug('rabbit: connection established');
344
- this.creatingConnection = false;
345
- this.em.emit(CONNECTION_CREATED_CONST, connection);
362
+ this.connectionsMap[connectionPurpose].creatingConnection = false;
363
+ this.em.emit(CONNECTION_CREATED_CONST, newConnection);
346
364
  isResolved = true;
347
- resolve(connection);
365
+ resolve(newConnection);
348
366
  });
349
367
  });
350
368
  }
351
369
 
352
- async getNewChannel({ name = rand().toString(), onClose = null, options = {} }: newChannelOpts = {}) {
353
- let connection!: AmqpConnectionManager;
370
+ async getNewChannel({
371
+ name = rand().toString(), onClose = null, options = {}, connectionPurpose = ConnectionPurpose.Consume,
372
+ }: newChannelOpts): Promise<ChannelWrapper> {
373
+ let connection!: AmqpConnectionManager | undefined | null;
354
374
  try {
355
- connection = await this.getConnection();
375
+ connection = await this.getConnection(connectionPurpose);
356
376
  } catch (e) {
357
377
  logger.error(`rabbit: error on get connection for new channel ${name} `, { e });
358
378
  throw e;
359
379
  }
380
+ if (!connection) {
381
+ throw new Error(`rabbit: couldnt get connection for new channel ${name}`);
382
+ }
360
383
  const channel = connection.createChannel({ ...options });
361
384
  once(channel, 'close').then((args) => {
362
385
  logger.error(`rabbit: channel ${name} closed`);
@@ -372,7 +395,7 @@ class RabbitMq implements IAfRabbitMq {
372
395
  }
373
396
  }
374
397
 
375
- async assertChannel({ force = false, newChannelOptions = {} }: assertChannelOpts = {}): Promise<ChannelWrapper> {
398
+ async assertChannel({ force = false, connectionPurpose = ConnectionPurpose.Consume }: assertChannelOpts): Promise<ChannelWrapper> {
376
399
  if (!this.publishChannelSetupPromise) {
377
400
  this.publishChannelSetupPromise = new Promise<ChannelWrapper>(async (resolve, reject) => {
378
401
  if (this.channel && !force) {
@@ -380,7 +403,7 @@ class RabbitMq implements IAfRabbitMq {
380
403
  }
381
404
 
382
405
  try {
383
- const channel = await this.getNewChannel({ options: newChannelOptions });
406
+ const channel = await this.getNewChannel({ connectionPurpose });
384
407
  channel.on('error', (err) => {
385
408
  logger.error('rabbit: channel error', { err });
386
409
  });
@@ -394,8 +417,8 @@ class RabbitMq implements IAfRabbitMq {
394
417
  return this.publishChannelSetupPromise;
395
418
  }
396
419
 
397
- async assertExchange(exchangeName: string) {
398
- const channel: ChannelWrapper = await this.assertChannel();
420
+ async assertExchange(exchangeName: string, options?: any) {
421
+ const channel: ChannelWrapper = await this.assertChannel({ connectionPurpose: options.connectionPurpose });
399
422
  if (this.exchanges[exchangeName]) {
400
423
  return this.exchanges[exchangeName];
401
424
  }
@@ -404,35 +427,36 @@ class RabbitMq implements IAfRabbitMq {
404
427
  return exchange;
405
428
  }
406
429
 
407
- async getQueueLength(queue: string) {
430
+ async getQueueLength(queue: string, connectionPurpose: ConnectionPurpose = ConnectionPurpose.Consume): Promise<Replies.AssertQueue> {
408
431
  RabbitMq.validateName('queue', queue);
432
+ const { connection } = this.connectionsMap[connectionPurpose];
409
433
  const { channel } = this;
410
434
  if (!channel) {
411
435
  throw new Error('channel is not defined');
412
436
  }
413
- debug('rabbit: getting queue length', { queue, connected: this.connection?.isConnected() });
437
+ debug('rabbit: getting queue length', { queue, connected: connection?.isConnected() });
414
438
  return channel?.checkQueue(queue);
415
439
  }
416
440
 
417
- private async deleteQueue(queue: string) {
441
+ private async deleteQueue(queue: string, connectionPurpose: ConnectionPurpose) {
418
442
  RabbitMq.validateName('queue', queue);
419
- const channel: ChannelWrapper = await this.assertChannel();
443
+ const channel: ChannelWrapper = await this.assertChannel({ connectionPurpose });
420
444
  logger.info('rabbit: deleting queue', { queue });
421
445
  const deleteQueueRes = await channel.deleteQueue(queue);
422
446
  debug('queue deleted', deleteQueueRes);
423
447
  return deleteQueueRes;
424
448
  }
425
449
 
426
- async bindQueue(queue: string, exchange: string) {
427
- const channel: ChannelWrapper = await this.assertChannel();
450
+ async bindQueue(queue: string, exchange: string, connectionPurpose: ConnectionPurpose) {
451
+ const channel: ChannelWrapper = await this.assertChannel({ connectionPurpose });
428
452
  await channel.addSetup((setupChannel: ConfirmChannel) => setupChannel.bindQueue(queue, exchange, ''));
429
453
  return channel.bindQueue(queue, exchange, '');
430
454
  }
431
455
 
432
- async setupQueue(queueName: string, options?: Options.AssertQueue): Promise<Replies.AssertQueue> {
456
+ async setupQueue(queueName: string, connectionPurpose: ConnectionPurpose, options?: Options.AssertQueue): Promise<Replies.AssertQueue> {
433
457
  let queue: Replies.AssertQueue;
434
458
  try {
435
- const channel: ChannelWrapper = await this.assertChannel();
459
+ const channel: ChannelWrapper = await this.assertChannel({ connectionPurpose });
436
460
  debug('assertQueue->channel.addSetup', { queueName });
437
461
  await channel.addSetup((setupChannel: ConfirmChannel) => setupChannel.assertQueue(queueName, options));
438
462
  debug('assertQueue->channel.assertQueue', { queueName });
@@ -441,8 +465,8 @@ class RabbitMq implements IAfRabbitMq {
441
465
  logger.error('rabbit: assertQueue error', { queueName, options, error: e });
442
466
  if (!this.options?.dontRetryAssert) {
443
467
  debug('retrying assertQueue', { queueName });
444
- const channel = await this.assertChannel({ force: true });
445
- await this.deleteQueue(queueName);
468
+ const channel = await this.assertChannel({ force: true, connectionPurpose });
469
+ await this.deleteQueue(queueName, connectionPurpose);
446
470
 
447
471
  debug('retrying assertQueue->channel.addSetup', { queueName });
448
472
  await channel.addSetup((setupChannel: ConfirmChannel) => setupChannel.assertQueue(queueName, options));
@@ -457,7 +481,7 @@ class RabbitMq implements IAfRabbitMq {
457
481
  return queue;
458
482
  }
459
483
 
460
- async assertQueue(queueName: string, options?: Options.AssertQueue) {
484
+ async assertQueue(queueName: string, connectionPurpose: ConnectionPurpose, options?: Options.AssertQueue) {
461
485
  RabbitMq.validateName('queue', queueName);
462
486
  if (this.queues[queueName]) {
463
487
  delete this.queueSetupPromises[queueName];
@@ -468,12 +492,12 @@ class RabbitMq implements IAfRabbitMq {
468
492
  return this.queueSetupPromises[queueName];
469
493
  }
470
494
 
471
- this.queueSetupPromises[queueName] = this.setupQueue(queueName, options);
495
+ this.queueSetupPromises[queueName] = this.setupQueue(queueName, connectionPurpose, options);
472
496
  return this.queueSetupPromises[queueName];
473
497
  }
474
498
 
475
499
  private saveConsumer(queue: string, callback: CallbackFunction, options: ConsumeOptions | undefined) {
476
- const isConsumerExist :boolean = this.consumers.some((consumer) => consumer.queue === queue);
500
+ const isConsumerExist: boolean = this.consumers.some((consumer) => consumer.queue === queue);
477
501
  if (!isConsumerExist) {
478
502
  logger.info(`rabbit: consumer: ${queue} saved in consumer array`);
479
503
  this.consumers.push({
@@ -522,11 +546,10 @@ class RabbitMq implements IAfRabbitMq {
522
546
  }
523
547
  logger.info(`rabbit: Consuming with lock from queue ${queue} with lockTimeout: ${lockTimeout}ms`);
524
548
  }
525
- const channel = await this.getNewChannel({});
549
+ const channel = await this.getNewChannel({ connectionPurpose: ConnectionPurpose.Consume });
526
550
  return channel.addSetup(async (confirmChannel: ConfirmChannel) => {
527
551
  await confirmChannel.assertQueue(queue, options ? { messageTtl: options.messageTtl } : undefined);
528
552
  await confirmChannel.prefetch(limit, true);
529
- const channelConsumerOptions = optionsWithDefaults.channelConsumeOptions ? merge(CONSUMER_DEFAULT_OPTIONS, optionsWithDefaults.channelConsumeOptions) : CONSUMER_DEFAULT_OPTIONS;
530
553
  const { consumerTag } = await confirmChannel.consume(
531
554
  queue,
532
555
  async (msg: ConsumeMessageOrNull) => {
@@ -598,8 +621,7 @@ class RabbitMq implements IAfRabbitMq {
598
621
  } catch (e) {
599
622
  await localNack(msg);
600
623
  }
601
- },
602
- channelConsumerOptions,
624
+ }, CONSUMER_DEFAULT_OPTIONS,
603
625
  );
604
626
  if (!consumerTag) {
605
627
  logger.error(`rabbit: failed to consume from queue ${queue}`);
@@ -610,13 +632,13 @@ class RabbitMq implements IAfRabbitMq {
610
632
  });
611
633
  }
612
634
 
613
- async consumeFromExchange(queue: string, exchange: string, callback: CallbackFunction, options?: ConsumeOptions) : Promise<any> {
635
+ async consumeFromExchange(queue: string, exchange: string, callback: CallbackFunction, options?: ConsumeOptions): Promise<any> {
614
636
  const optionsWithDefaults = { ...DEFAULT_OPTIONS, ...options };
615
637
  RabbitMq.validateName('exchange', exchange);
616
638
  RabbitMq.validateName('queue', queue);
617
639
  const { limit, deadMessageTtl } = optionsWithDefaults;
618
640
  await this.saveConsumer(queue, callback, options);
619
- const channel: ChannelWrapper = await this.getNewChannel({ name: `consume-exchange-${exchange}-queue-${queue}` });
641
+ const channel: ChannelWrapper = await this.getNewChannel({ name: `consume - exchange - ${exchange} -queue - ${queue}`, connectionPurpose: ConnectionPurpose.Consume });
620
642
 
621
643
  return channel.addSetup(async (c: ConfirmChannel) => {
622
644
  const assertExchange = await assertExchangeFanout(c, exchange);
@@ -634,11 +656,11 @@ class RabbitMq implements IAfRabbitMq {
634
656
  });
635
657
  }
636
658
 
637
- async publish(exchange: string, content: any, customHeaders?: any, options?: PublishOptions): Promise<boolean> {
659
+ async publish(exchange: string, content: any, customHeaders?: any): Promise<boolean> {
638
660
  return wrapSetImmediate(async () => {
639
661
  RabbitMq.validateName('exchange', exchange);
640
- const channel: ChannelWrapper = await this.assertChannel({ newChannelOptions: options?.newChannelOptions });
641
- await this.assertExchange(exchange);
662
+ const channel: ChannelWrapper = await this.assertChannel({ connectionPurpose: ConnectionPurpose.Publish });
663
+ await this.assertExchange(exchange, { connectionPurpose: ConnectionPurpose.Publish });
642
664
  await channel.publish(exchange, '',
643
665
  Buffer.from(JSON.stringify(content)),
644
666
  RabbitMq.getPublishOptions(customHeaders));
@@ -652,7 +674,7 @@ class RabbitMq implements IAfRabbitMq {
652
674
  customHeaders?: any,
653
675
  ): Promise<boolean | undefined> {
654
676
  try {
655
- await this.assertChannel({ newChannelOptions: options?.newChannelOptions });
677
+ await this.assertChannel({ connectionPurpose: ConnectionPurpose.Publish });
656
678
  } catch (e) {
657
679
  logger.error(`rabbit sendToQueue: failed to send assert channel when sending to queue ${queue}`, { e });
658
680
  throw e;
@@ -660,7 +682,7 @@ class RabbitMq implements IAfRabbitMq {
660
682
 
661
683
  try {
662
684
  RabbitMq.validateName('queue', queue);
663
- await this.assertQueue(queue, options);
685
+ await this.assertQueue(queue, ConnectionPurpose.Publish, options);
664
686
  } catch (e) {
665
687
  logger.error(`rabbit sendToQueue: failed to assert queue ${queue}`, { e });
666
688
  throw e;
@@ -673,20 +695,24 @@ class RabbitMq implements IAfRabbitMq {
673
695
  debug(`rabbit: sending to queue ${queue}`, { res });
674
696
  return res;
675
697
  } catch (e) {
676
- const isConnected = await this.isConnected();
698
+ const isConnected = await this.isConnected(ConnectionPurpose.Publish);
677
699
  logger.error(`rabbit sendToQueue: failed to send to queue ${queue}, isConnected: ${isConnected}`, { e });
678
700
  throw e;
679
701
  }
680
702
  }
681
703
 
682
- async isConnected() : Promise<boolean> {
683
- const connection = await this.getConnection();
704
+ async isConnected(connectionPurpose: ConnectionPurpose): Promise<boolean> {
705
+ const connection = await this.getConnection(connectionPurpose);
706
+ if (!connection) {
707
+ logger.error('rabbit: isConnected - false');
708
+ return false;
709
+ }
684
710
  const isConnected = connection.isConnected();
685
711
  if (!isConnected) {
686
712
  logger.error('rabbit: isConnected - false');
687
713
  return false;
688
714
  }
689
- const channel: any = await this.assertChannel();
715
+ const channel: any = await this.assertChannel({ connectionPurpose });
690
716
  try {
691
717
  await Promise.all([
692
718
  channel.waitForConnect(),
@@ -700,7 +726,7 @@ class RabbitMq implements IAfRabbitMq {
700
726
  return true;
701
727
  }
702
728
 
703
- async gracefulShutdown(signal: string) : Promise<void> {
729
+ async gracefulShutdown(signal: string): Promise<void> {
704
730
  const tagsNumber = this.consumersTags.length;
705
731
  logger.info(`rabbit: [gracefully-shutdown] received ${signal}! canceling #${tagsNumber} tags...`);
706
732
  const cancelTagPromises = this.consumersTags.map(([channel, tag]) => channel.cancel(tag));
package/src/lib/types.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { CreateChannelOpts } from 'amqp-connection-manager';
1
+ import { AmqpConnectionManager } from 'amqp-connection-manager';
2
2
  import { ConsumeMessage, Options, Replies } from 'amqplib';
3
3
 
4
4
  export interface ExchangesCache {
@@ -28,7 +28,6 @@ export interface ConsumeOptions {
28
28
  useConsumeWithLock?: boolean;
29
29
  auditContext?: any;
30
30
  enableRabbitTrace?: boolean;
31
- channelConsumeOptions?: Options.Consume;
32
31
  }
33
32
 
34
33
  export type CallbackFunction = (msg: ConsumeMessage, ack: any, nack: any) => Promise<any>
@@ -36,18 +35,11 @@ export type CallbackFunction = (msg: ConsumeMessage, ack: any, nack: any) => Pro
36
35
  export type newChannelOpts = {
37
36
  name?: string;
38
37
  onClose?: null | ((args: any | null) => void);
39
- options?: CreateChannelOpts | undefined;
40
38
  };
41
39
  export type assertChannelOpts = {
42
40
  channelName?: string;
43
41
  force?: boolean;
44
- newChannelOptions?: newChannelOpts;
45
42
  }
46
-
47
- export interface PublishOptions {
48
- newChannelOptions?: newChannelOpts;
49
- }
50
-
51
43
  export type AfConsumer = {
52
44
  queue: string;
53
45
  callback: CallbackFunction;
@@ -64,3 +56,13 @@ export const CONSUMER_DEFAULT_OPTIONS: Options.Consume = {
64
56
  [HA_PROMOTE_ON_SHUTDOWN]: 'always',
65
57
  },
66
58
  };
59
+
60
+ export type ConnectionData = {
61
+ connection: AmqpConnectionManager | null;
62
+ creatingConnection: boolean;
63
+ };
64
+
65
+ export enum ConnectionPurpose {
66
+ Consume = 'consume',
67
+ Publish = 'publish',
68
+ }