@autofleet/rabbit 3.2.19-beta.6 → 3.2.19-beta.7

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,7 +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 { CallbackFunction, ConsumeMessageOrNull, ConsumeOptions, CustomMessageHeaders, QueuesCache, RedisLockType, ExchangesCache, QueueSetupPromisesDictionary } from './lib/types';
6
+ import { CallbackFunction, ConsumeMessageOrNull, ConsumeOptions, CustomMessageHeaders, QueuesCache, RedisLockType, ExchangesCache, QueueSetupPromisesDictionary, ConnectionRole } from './lib/types';
7
7
  export interface IAfRabbitMq {
8
8
  ack: any;
9
9
  nack: any;
@@ -37,10 +37,12 @@ type newChannelOpts = {
37
37
  name?: string;
38
38
  onClose?: null | ((args: any | null) => void);
39
39
  options?: CreateChannelOpts | undefined;
40
+ connectionRole: ConnectionRole;
40
41
  };
41
42
  type assertChannelOpts = {
42
43
  channelName?: string;
43
44
  force?: boolean;
45
+ connectionRole: ConnectionRole;
44
46
  };
45
47
  declare class RabbitMq implements IAfRabbitMq {
46
48
  static parseMsg(msg: any): any;
@@ -58,10 +60,13 @@ declare class RabbitMq implements IAfRabbitMq {
58
60
  DISCONNECT_MSG: string;
59
61
  RECONNECT_MSG: string;
60
62
  channel: ChannelWrapper | null;
63
+ publishChannelSetupPromise: Promise<ChannelWrapper> | null;
61
64
  blockReconnect: boolean | null | undefined;
62
- connection: AmqpConnectionManager | null | undefined;
65
+ consumeConnection: AmqpConnectionManager | null | undefined;
66
+ publishConnection: AmqpConnectionManager | null | undefined;
63
67
  em: EventEmitter;
64
- creatingConnection: boolean;
68
+ creatingConsumeConnection: boolean;
69
+ creatingPublishConnection: boolean;
65
70
  exchanges: ExchangesCache;
66
71
  queues: QueuesCache;
67
72
  queueSetupPromises: QueueSetupPromisesDictionary;
@@ -75,15 +80,19 @@ declare class RabbitMq implements IAfRabbitMq {
75
80
  private shouldConsumeMessageByTimestamp;
76
81
  ack: (channel: ConfirmChannel, msg: ConsumeMessageOrNull, shouldUpdateRedisTimestamp?: boolean, releaseLock?: null) => (userMsg: ConsumeMessage) => Promise<any>;
77
82
  nack: (channel: ConfirmChannel, queue: string, options: any, deadQueueOptions: Options.AssertQueue, msg: ConsumeMessageOrNull, releaseLock: any) => (userMsg: ConsumeMessageOrNull, { skipRetry, }?: NackOptions) => Promise<any>;
78
- getConnection(): Promise<AmqpConnectionManager>;
79
- getNewChannel({ name, onClose, options }?: newChannelOpts): Promise<ChannelWrapper>;
80
- assertChannel({ force }?: assertChannelOpts): Promise<ChannelWrapper>;
83
+ geConnectionByRole: (connectionRole: ConnectionRole) => {
84
+ connectionByRole: AmqpConnectionManager | null | undefined;
85
+ creatingConnectionByRole: boolean;
86
+ };
87
+ getConnection(connectionRole: ConnectionRole): Promise<AmqpConnectionManager | null | undefined>;
88
+ getNewChannel({ name, onClose, options, connectionRole, }?: newChannelOpts): Promise<ChannelWrapper>;
89
+ assertChannel({ force, connectionRole }?: assertChannelOpts): Promise<ChannelWrapper>;
81
90
  assertExchange(exchangeName: string, options?: any): Promise<any>;
82
- getQueueLength(queue: string): Promise<Replies.AssertQueue>;
91
+ getQueueLength(queue: string, connectionRole?: ConnectionRole): Promise<Replies.AssertQueue>;
83
92
  private deleteQueue;
84
- bindQueue(queue: string, exchange: string): Promise<void>;
85
- setupQueue(queueName: string, options?: Options.AssertQueue): Promise<Replies.AssertQueue>;
86
- assertQueue(queueName: string, options?: Options.AssertQueue): Promise<any>;
93
+ bindQueue(queue: string, exchange: string, connectionRole: ConnectionRole): Promise<void>;
94
+ setupQueue(queueName: string, connectionRole: ConnectionRole, options?: Options.AssertQueue): Promise<Replies.AssertQueue>;
95
+ assertQueue(queueName: string, connectionRole: ConnectionRole, options?: Options.AssertQueue): Promise<any>;
87
96
  private saveConsumer;
88
97
  consume(queue: string, callback: CallbackFunction, options?: ConsumeOptions): Promise<any>;
89
98
  private lockRedisIfNeeded;
@@ -91,8 +100,8 @@ declare class RabbitMq implements IAfRabbitMq {
91
100
  private consumeFromRabbit;
92
101
  consumeFromExchange(queue: string, exchange: string, callback: CallbackFunction, options?: ConsumeOptions): Promise<any>;
93
102
  publish(exchange: string, content: any, customHeaders?: any): Promise<boolean>;
94
- sendToQueue(queue: string, content: any, options?: any, customHeaders?: any, isBlocking?: boolean): Promise<boolean | undefined>;
95
- isConnected(): Promise<boolean>;
103
+ sendToQueue(queue: string, content: any, options?: any, customHeaders?: any): Promise<boolean | undefined>;
104
+ isConnected(connectionRole: ConnectionRole): Promise<boolean>;
96
105
  gracefulShutdown(signal: string): Promise<void>;
97
106
  }
98
107
  export default RabbitMq;
package/dist/index.js CHANGED
@@ -115,10 +115,16 @@ class RabbitMq {
115
115
  });
116
116
  }
117
117
  };
118
+ this.geConnectionByRole = (connectionRole) => (connectionRole === types_1.ConnectionRole.Consumer
119
+ ? { connectionByRole: this.consumeConnection, creatingConnectionByRole: this.creatingConsumeConnection }
120
+ : { connectionByRole: this.publishConnection, creatingConnectionByRole: this.creatingPublishConnection });
118
121
  this.em = new events_1.EventEmitter();
119
122
  this.channel = null;
120
- this.connection = null;
121
- this.creatingConnection = false;
123
+ this.publishChannelSetupPromise = null;
124
+ this.consumeConnection = null;
125
+ this.publishConnection = null;
126
+ this.creatingPublishConnection = false;
127
+ this.creatingConsumeConnection = false;
122
128
  this.exchanges = {};
123
129
  this.queues = {};
124
130
  this.queueSetupPromises = {};
@@ -139,30 +145,31 @@ class RabbitMq {
139
145
  });
140
146
  }
141
147
  }
142
- async getConnection() {
148
+ async getConnection(connectionRole) {
143
149
  return new Promise(async (resolve, reject) => {
150
+ let { connectionByRole, creatingConnectionByRole } = this.geConnectionByRole(connectionRole);
144
151
  if (this.blockReconnect) {
145
152
  debug('rabbit: block reconnect');
146
153
  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
147
154
  // @ts-ignore
148
155
  return resolve();
149
156
  }
150
- if (this.connection !== null) {
151
- if (this.options?.disableReconnect || this.connection?.isConnected()) {
157
+ if (connectionByRole !== null) {
158
+ if (this.options?.disableReconnect || connectionByRole?.isConnected()) {
152
159
  debug('rabbit: connection - is connected');
153
160
  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
154
161
  // @ts-ignore
155
- return resolve(this.connection);
162
+ return resolve(connectionByRole);
156
163
  }
157
164
  debug('rabbit: connection - reconnecting');
158
165
  }
159
- if (this.creatingConnection) {
166
+ if (creatingConnectionByRole) {
160
167
  debug('rabbit: creating connection emi');
161
168
  this.em.once(consts_1.CONNECTION_CREATED_CONST, resolve);
162
169
  this.em.once(consts_1.CONNECTION_FAILED_CONST, reject);
163
170
  return;
164
171
  }
165
- this.creatingConnection = true;
172
+ creatingConnectionByRole = true;
166
173
  let isResolved = false;
167
174
  // It is import to use it as a function and not as a variable
168
175
  // because of k8s changes the env variables
@@ -175,11 +182,15 @@ class RabbitMq {
175
182
  return [`amqp://${userName}:${password}@${host}?heartbeat=${HEARTBEAT}`];
176
183
  };
177
184
  const defaultUrls = findServers();
178
- const connection = await (0, amqp_connection_manager_1.connect)(defaultUrls, {
185
+ const newConnection = await (0, amqp_connection_manager_1.connect)(defaultUrls, {
179
186
  findServers,
180
187
  });
181
- this.connection = connection;
182
- this.connection.on('error', (err) => {
188
+ if (!newConnection) {
189
+ logger_1.default.error('rabbit: couldnt create a connection');
190
+ return resolve(connectionByRole);
191
+ }
192
+ connectionByRole = newConnection;
193
+ connectionByRole.on('error', (err) => {
183
194
  logger_1.default.error('rabbit: connection error', { err });
184
195
  if (!isResolved) {
185
196
  isResolved = true;
@@ -187,7 +198,7 @@ class RabbitMq {
187
198
  this.em.emit(consts_1.CONNECTION_FAILED_CONST, err);
188
199
  }
189
200
  });
190
- this.connection.on('connectFailed', (err) => {
201
+ connectionByRole.on('connectFailed', (err) => {
191
202
  this.consumersTags = [];
192
203
  logger_1.default.error('rabbit: connection connectFailed', { err });
193
204
  if (!isResolved) {
@@ -196,7 +207,7 @@ class RabbitMq {
196
207
  this.em.emit(consts_1.CONNECTION_FAILED_CONST, err);
197
208
  }
198
209
  });
199
- this.connection.on('disconnect', ({ err }) => {
210
+ connectionByRole.on('disconnect', ({ err }) => {
200
211
  this.consumersTags = [];
201
212
  debug('rabbit: connection closed');
202
213
  if (this.options?.disableReconnect) {
@@ -207,24 +218,27 @@ class RabbitMq {
207
218
  logger_1.default.error(`${this.RECONNECT_MSG}${err && ` - ${err}`}`);
208
219
  }
209
220
  });
210
- this.connection.once('connect', async () => {
221
+ connectionByRole.once('connect', async () => {
211
222
  debug('rabbit: connection established');
212
- this.creatingConnection = false;
213
- this.em.emit(consts_1.CONNECTION_CREATED_CONST, connection);
223
+ creatingConnectionByRole = false;
224
+ this.em.emit(consts_1.CONNECTION_CREATED_CONST, connectionByRole);
214
225
  isResolved = true;
215
- resolve(connection);
226
+ resolve(connectionByRole);
216
227
  });
217
228
  });
218
229
  }
219
- async getNewChannel({ name = (0, utils_1.rand)().toString(), onClose = null, options = {} } = {}) {
230
+ async getNewChannel({ name = (0, utils_1.rand)().toString(), onClose = null, options = {}, connectionRole, } = { connectionRole: types_1.ConnectionRole.Consumer }) {
220
231
  let connection;
221
232
  try {
222
- connection = await this.getConnection();
233
+ connection = await this.getConnection(connectionRole);
223
234
  }
224
235
  catch (e) {
225
236
  logger_1.default.error(`rabbit: error on get connection for new channel ${name} `, { e });
226
237
  throw e;
227
238
  }
239
+ if (!connection) {
240
+ throw new Error(`rabbit: couldnt get connection for new channel ${name}`);
241
+ }
228
242
  const channel = connection.createChannel({ ...options });
229
243
  (0, events_1.once)(channel, 'close').then((args) => {
230
244
  logger_1.default.error(`rabbit: channel ${name} closed`);
@@ -240,26 +254,29 @@ class RabbitMq {
240
254
  throw err;
241
255
  }
242
256
  }
243
- async assertChannel({ force = false } = {}) {
244
- return new Promise(async (resolve, reject) => {
245
- if (this.channel && !force) {
246
- return resolve(this.channel);
247
- }
248
- try {
249
- const channel = await this.getNewChannel({});
250
- channel.on('error', (err) => {
251
- logger_1.default.error('rabbit: channel error', { err });
252
- });
253
- this.channel = channel;
254
- resolve(channel);
255
- }
256
- catch (e) {
257
- reject(e);
258
- }
259
- });
257
+ async assertChannel({ force = false, connectionRole } = { connectionRole: types_1.ConnectionRole.Consumer }) {
258
+ if (!this.publishChannelSetupPromise) {
259
+ this.publishChannelSetupPromise = new Promise(async (resolve, reject) => {
260
+ if (this.channel && !force) {
261
+ return resolve(this.channel);
262
+ }
263
+ try {
264
+ const channel = await this.getNewChannel({ connectionRole });
265
+ channel.on('error', (err) => {
266
+ logger_1.default.error('rabbit: channel error', { err });
267
+ });
268
+ this.channel = channel;
269
+ resolve(channel);
270
+ }
271
+ catch (e) {
272
+ reject(e);
273
+ }
274
+ });
275
+ }
276
+ return this.publishChannelSetupPromise;
260
277
  }
261
278
  async assertExchange(exchangeName, options) {
262
- const channel = await this.assertChannel();
279
+ const channel = await this.assertChannel({ connectionRole: options.connectionRole });
263
280
  if (this.exchanges[exchangeName]) {
264
281
  return this.exchanges[exchangeName];
265
282
  }
@@ -267,32 +284,33 @@ class RabbitMq {
267
284
  this.exchanges[exchangeName] = exchange;
268
285
  return exchange;
269
286
  }
270
- async getQueueLength(queue) {
287
+ async getQueueLength(queue, connectionRole = types_1.ConnectionRole.Consumer) {
271
288
  RabbitMq.validateName('queue', queue);
289
+ const { connectionByRole } = this.geConnectionByRole(connectionRole);
272
290
  const { channel } = this;
273
291
  if (!channel) {
274
292
  throw new Error('channel is not defined');
275
293
  }
276
- debug('rabbit: getting queue length', { queue, connected: this.connection?.isConnected() });
294
+ debug('rabbit: getting queue length', { queue, connected: connectionByRole?.isConnected() });
277
295
  return channel?.checkQueue(queue);
278
296
  }
279
- async deleteQueue(queue) {
297
+ async deleteQueue(queue, connectionRole) {
280
298
  RabbitMq.validateName('queue', queue);
281
- const channel = await this.assertChannel();
299
+ const channel = await this.assertChannel({ connectionRole });
282
300
  logger_1.default.info('rabbit: deleting queue', { queue });
283
301
  const deleteQueueRes = await channel.deleteQueue(queue);
284
302
  debug('queue deleted', deleteQueueRes);
285
303
  return deleteQueueRes;
286
304
  }
287
- async bindQueue(queue, exchange) {
288
- const channel = await this.assertChannel();
305
+ async bindQueue(queue, exchange, connectionRole) {
306
+ const channel = await this.assertChannel({ connectionRole });
289
307
  await channel.addSetup((setupChannel) => setupChannel.bindQueue(queue, exchange, ''));
290
308
  return channel.bindQueue(queue, exchange, '');
291
309
  }
292
- async setupQueue(queueName, options) {
310
+ async setupQueue(queueName, connectionRole, options) {
293
311
  let queue;
294
312
  try {
295
- const channel = await this.assertChannel();
313
+ const channel = await this.assertChannel({ connectionRole });
296
314
  debug('assertQueue->channel.addSetup', { queueName });
297
315
  await channel.addSetup((setupChannel) => setupChannel.assertQueue(queueName, options));
298
316
  debug('assertQueue->channel.assertQueue', { queueName });
@@ -302,8 +320,8 @@ class RabbitMq {
302
320
  logger_1.default.error('rabbit: assertQueue error', { queueName, options, error: e });
303
321
  if (!this.options?.dontRetryAssert) {
304
322
  debug('retrying assertQueue', { queueName });
305
- const channel = await this.assertChannel({ force: true });
306
- await this.deleteQueue(queueName);
323
+ const channel = await this.assertChannel({ force: true, connectionRole });
324
+ await this.deleteQueue(queueName, connectionRole);
307
325
  debug('retrying assertQueue->channel.addSetup', { queueName });
308
326
  await channel.addSetup((setupChannel) => setupChannel.assertQueue(queueName, options));
309
327
  debug('retrying assertQueue->channel.assertQueue', { queueName });
@@ -316,7 +334,7 @@ class RabbitMq {
316
334
  this.queues[queueName] = queueName;
317
335
  return queue;
318
336
  }
319
- async assertQueue(queueName, options) {
337
+ async assertQueue(queueName, connectionRole, options) {
320
338
  RabbitMq.validateName('queue', queueName);
321
339
  if (this.queues[queueName]) {
322
340
  delete this.queueSetupPromises[queueName];
@@ -325,7 +343,7 @@ class RabbitMq {
325
343
  if (this.queueSetupPromises[queueName]) {
326
344
  return this.queueSetupPromises[queueName];
327
345
  }
328
- this.queueSetupPromises[queueName] = this.setupQueue(queueName, options);
346
+ this.queueSetupPromises[queueName] = this.setupQueue(queueName, connectionRole, options);
329
347
  return this.queueSetupPromises[queueName];
330
348
  }
331
349
  saveConsumer(queue, callback, options) {
@@ -368,7 +386,7 @@ class RabbitMq {
368
386
  }
369
387
  logger_1.default.info(`rabbit: Consuming with lock from queue ${queue} with lockTimeout: ${lockTimeout}ms`);
370
388
  }
371
- const channel = await this.getNewChannel({});
389
+ const channel = await this.getNewChannel({ connectionRole: types_1.ConnectionRole.Consumer });
372
390
  return channel.addSetup(async (confirmChannel) => {
373
391
  await confirmChannel.assertQueue(queue, options ? { messageTtl: options.messageTtl } : undefined);
374
392
  await confirmChannel.prefetch(limit, true);
@@ -448,7 +466,7 @@ class RabbitMq {
448
466
  RabbitMq.validateName('queue', queue);
449
467
  const { limit, deadMessageTtl } = optionsWithDefaults;
450
468
  await this.saveConsumer(queue, callback, options);
451
- const channel = await this.getNewChannel({ name: `consume-exchange-${exchange}-queue-${queue}` });
469
+ const channel = await this.getNewChannel({ name: `consume - exchange - ${exchange} -queue - ${queue}`, connectionRole: types_1.ConnectionRole.Consumer });
452
470
  return channel.addSetup(async (c) => {
453
471
  const assertExchange = await (0, utils_1.assertExchangeFanout)(c, exchange);
454
472
  await c.assertQueue(queue);
@@ -463,33 +481,44 @@ class RabbitMq {
463
481
  async publish(exchange, content, customHeaders) {
464
482
  return (0, utils_1.wrapSetImmediate)(async () => {
465
483
  RabbitMq.validateName('exchange', exchange);
466
- const channel = await this.assertChannel();
467
- await this.assertExchange(exchange);
484
+ const channel = await this.assertChannel({ connectionRole: types_1.ConnectionRole.Publisher });
485
+ await this.assertExchange(exchange, { connectionRole: types_1.ConnectionRole.Publisher });
468
486
  await channel.publish(exchange, '', Buffer.from(JSON.stringify(content)), RabbitMq.getPublishOptions(customHeaders));
469
487
  });
470
488
  }
471
- async sendToQueue(queue, content, options, customHeaders, isBlocking) {
472
- const callback = async () => {
473
- try {
474
- RabbitMq.validateName('queue', queue);
475
- await this.assertChannel();
476
- await this.assertQueue(queue, options);
477
- const res = await this.channel?.sendToQueue(queue, Buffer.from(JSON.stringify(content)), RabbitMq.getPublishOptions(customHeaders));
478
- debug(`rabbit: sending to queue ${queue}`, { res });
479
- return res;
480
- }
481
- catch (e) {
482
- logger_1.default.error(`rabbit: failed to send to queue ${queue}`, { e });
483
- throw e;
484
- }
485
- };
486
- if (isBlocking) {
487
- return callback();
489
+ async sendToQueue(queue, content, options, customHeaders) {
490
+ try {
491
+ await this.assertChannel({ connectionRole: types_1.ConnectionRole.Publisher });
492
+ }
493
+ catch (e) {
494
+ logger_1.default.error(`rabbit sendToQueue: failed to send assert channel when sending to queue ${queue}`, { e });
495
+ throw e;
496
+ }
497
+ try {
498
+ RabbitMq.validateName('queue', queue);
499
+ await this.assertQueue(queue, types_1.ConnectionRole.Publisher, options);
500
+ }
501
+ catch (e) {
502
+ logger_1.default.error(`rabbit sendToQueue: failed to assert queue ${queue}`, { e });
503
+ throw e;
504
+ }
505
+ try {
506
+ const res = await this.channel?.sendToQueue(queue, Buffer.from(JSON.stringify(content)), RabbitMq.getPublishOptions(customHeaders));
507
+ debug(`rabbit: sending to queue ${queue}`, { res });
508
+ return res;
509
+ }
510
+ catch (e) {
511
+ const isConnected = await this.isConnected(types_1.ConnectionRole.Publisher);
512
+ logger_1.default.error(`rabbit sendToQueue: failed to send to queue ${queue}, isConnected: ${isConnected}`, { e });
513
+ throw e;
488
514
  }
489
- return (0, utils_1.wrapSetImmediate)(callback);
490
515
  }
491
- async isConnected() {
492
- const connection = await this.getConnection();
516
+ async isConnected(connectionRole) {
517
+ const connection = await this.getConnection(connectionRole);
518
+ if (!connection) {
519
+ logger_1.default.error('rabbit: isConnected - false');
520
+ return false;
521
+ }
493
522
  const isConnected = connection.isConnected();
494
523
  if (!isConnected) {
495
524
  logger_1.default.error('rabbit: isConnected - false');
@@ -38,3 +38,7 @@ export type AfConsumer = {
38
38
  options: ConsumeOptions | undefined;
39
39
  };
40
40
  export declare const CONSUMER_DEFAULT_OPTIONS: Options.Consume;
41
+ export declare enum ConnectionRole {
42
+ Consumer = "consumer",
43
+ Publisher = "publisher"
44
+ }
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.ConnectionRole = 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 ConnectionRole;
13
+ (function (ConnectionRole) {
14
+ ConnectionRole["Consumer"] = "consumer";
15
+ ConnectionRole["Publisher"] = "publisher";
16
+ })(ConnectionRole = exports.ConnectionRole || (exports.ConnectionRole = {}));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@autofleet/rabbit",
3
- "version": "3.2.19-beta.6",
3
+ "version": "3.2.19-beta.7",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "scripts": {
package/src/index.ts CHANGED
@@ -283,7 +283,7 @@ class RabbitMq implements IAfRabbitMq {
283
283
  : { connectionByRole: this.publishConnection, creatingConnectionByRole: this.creatingPublishConnection });
284
284
 
285
285
  async getConnection(connectionRole: ConnectionRole) {
286
- return new Promise<AmqpConnectionManager>(async (resolve, reject) => {
286
+ return new Promise<AmqpConnectionManager | undefined | null>(async (resolve, reject) => {
287
287
  let { connectionByRole, creatingConnectionByRole } = this.geConnectionByRole(connectionRole);
288
288
  if (this.blockReconnect) {
289
289
  debug('rabbit: block reconnect');
@@ -296,7 +296,7 @@ class RabbitMq implements IAfRabbitMq {
296
296
  debug('rabbit: connection - is connected');
297
297
  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
298
298
  // @ts-ignore
299
- return resolve(this.connection);
299
+ return resolve(connectionByRole);
300
300
  }
301
301
  debug('rabbit: connection - reconnecting');
302
302
  }
@@ -327,7 +327,13 @@ class RabbitMq implements IAfRabbitMq {
327
327
  findServers,
328
328
  });
329
329
 
330
+ if (!newConnection) {
331
+ logger.error('rabbit: couldnt create a connection');
332
+ return resolve(connectionByRole);
333
+ }
334
+
330
335
  connectionByRole = newConnection;
336
+
331
337
  connectionByRole.on('error', (err) => {
332
338
  logger.error('rabbit: connection error', { err });
333
339
  if (!isResolved) {
@@ -370,13 +376,16 @@ class RabbitMq implements IAfRabbitMq {
370
376
  async getNewChannel({
371
377
  name = rand().toString(), onClose = null, options = {}, connectionRole,
372
378
  }: newChannelOpts = { connectionRole: ConnectionRole.Consumer }): Promise<ChannelWrapper> {
373
- let connection!: AmqpConnectionManager;
379
+ let connection!: AmqpConnectionManager | undefined | null;
374
380
  try {
375
381
  connection = await this.getConnection(connectionRole);
376
382
  } catch (e) {
377
383
  logger.error(`rabbit: error on get connection for new channel ${name} `, { e });
378
384
  throw e;
379
385
  }
386
+ if (!connection) {
387
+ throw new Error(`rabbit: couldnt get connection for new channel ${name}`);
388
+ }
380
389
  const channel = connection.createChannel({ ...options });
381
390
  once(channel, 'close').then((args) => {
382
391
  logger.error(`rabbit: channel ${name} closed`);
@@ -424,7 +433,7 @@ class RabbitMq implements IAfRabbitMq {
424
433
  return exchange;
425
434
  }
426
435
 
427
- async getQueueLength(queue: string, connectionRole: ConnectionRole) {
436
+ async getQueueLength(queue: string, connectionRole: ConnectionRole = ConnectionRole.Consumer): Promise<Replies.AssertQueue> {
428
437
  RabbitMq.validateName('queue', queue);
429
438
  const { connectionByRole } = this.geConnectionByRole(connectionRole);
430
439
  const { channel } = this;
@@ -700,6 +709,10 @@ class RabbitMq implements IAfRabbitMq {
700
709
 
701
710
  async isConnected(connectionRole: ConnectionRole): Promise<boolean> {
702
711
  const connection = await this.getConnection(connectionRole);
712
+ if (!connection) {
713
+ logger.error('rabbit: isConnected - false');
714
+ return false;
715
+ }
703
716
  const isConnected = connection.isConnected();
704
717
  if (!isConnected) {
705
718
  logger.error('rabbit: isConnected - false');
package/src/lib/types.ts CHANGED
@@ -56,4 +56,7 @@ export const CONSUMER_DEFAULT_OPTIONS: Options.Consume = {
56
56
  },
57
57
  };
58
58
 
59
- export type ConnectionRole = 'consumer' | 'publisher';
59
+ export enum ConnectionRole {
60
+ Consumer = 'consumer',
61
+ Publisher = 'publisher',
62
+ }