@autofleet/rabbit 3.4.0-beta--beta--0.0 → 3.4.0-beta.1

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/src/index.ts CHANGED
@@ -1,5 +1,4 @@
1
- /* eslint-disable no-empty,consistent-return,no-async-promise-executor,@typescript-eslint/no-unused-vars */
2
-
1
+ /* eslint-disable no-empty,consistent-return,no-async-promise-executor,@typescript-eslint/no-unused-vars,no-param-reassign */
3
2
  import { EventEmitter, once } from 'events';
4
3
  import { promisify } from 'util';
5
4
  import moment from 'moment';
@@ -20,8 +19,6 @@ import getRedisInstance, { RedisConfig } from './lib/redis';
20
19
  import { assertExchangeFanout, rand, wrapSetImmediate } from './lib/utils';
21
20
  import {
22
21
  AUTOMATION_ID_HEADER,
23
- CONNECTION_CREATED_CONST,
24
- CONNECTION_FAILED_CONST,
25
22
  DEFAULT_LOCK_TIMEOUT,
26
23
  DEFAULT_OPTIONS,
27
24
  RETRY_HEADER,
@@ -40,8 +37,8 @@ import {
40
37
  CONSUMER_DEFAULT_OPTIONS,
41
38
  QueueSetupPromisesDictionary,
42
39
  AssertExchangePromisesDictionary,
40
+ ConnectionData,
43
41
  } from './lib/types';
44
- import { SendTaskOptions, TaskData } from './lib/celery';
45
42
 
46
43
  // const debug = nodeDebug('af-rabbitmq')
47
44
  const debug = logger.debug.bind(logger);
@@ -87,11 +84,13 @@ type newChannelOpts = {
87
84
  name?: string;
88
85
  onClose?: null | ((args: any | null) => void);
89
86
  options?: CreateChannelOpts | undefined;
87
+ connection: ConnectionData;
90
88
  };
91
89
 
92
90
  type assertChannelOpts = {
93
91
  channelName?: string;
94
92
  force?: boolean;
93
+ connection: ConnectionData;
95
94
  }
96
95
 
97
96
  type AfConsumer = {
@@ -144,7 +143,7 @@ class RabbitMq implements IAfRabbitMq {
144
143
 
145
144
  RECONNECT_MSG = 'rabbit: connection disconnect - reconnecting';
146
145
 
147
- channel: ChannelWrapper | null;
146
+ publishChannel: ChannelWrapper | null;
148
147
 
149
148
  publishChannelSetupPromise: Promise<ChannelWrapper> | null;
150
149
 
@@ -152,6 +151,10 @@ class RabbitMq implements IAfRabbitMq {
152
151
 
153
152
  connection: AmqpConnectionManager | null | undefined
154
153
 
154
+ publishConnection: ConnectionData
155
+
156
+ consumeConnection: ConnectionData
157
+
155
158
  em: EventEmitter;
156
159
 
157
160
  creatingConnection: boolean;
@@ -180,13 +183,15 @@ class RabbitMq implements IAfRabbitMq {
180
183
  private vhost = 'quorum-vhost';
181
184
 
182
185
  // TODO:[QUORUM-PHASE-3] Delete the old properties that we use for the old consumers and publishers
183
- oldChannel: ChannelWrapper | null;
186
+ oldPublishChannel: ChannelWrapper | null;
184
187
 
185
188
  oldPublishChannelSetupPromise: Promise<ChannelWrapper> | null;
186
189
 
187
190
  oldBlockReconnect: boolean | null | undefined
188
191
 
189
- oldConnection: AmqpConnectionManager | null | undefined
192
+ oldPublishConnection: ConnectionData
193
+
194
+ oldConsumeConnection: ConnectionData
190
195
 
191
196
  oldEm: EventEmitter;
192
197
 
@@ -206,9 +211,23 @@ class RabbitMq implements IAfRabbitMq {
206
211
 
207
212
  constructor(options: AfRabbitOptions = {}, redisConfig?: RedisConfig) {
208
213
  this.em = new EventEmitter();
209
- this.channel = null;
214
+ this.publishChannel = null;
210
215
  this.publishChannelSetupPromise = null;
211
216
  this.connection = null;
217
+ this.publishConnection = {
218
+ connection: null,
219
+ creatingConnection: false,
220
+ connectionCreatedEventName: 'publishConnectionCreated',
221
+ connectionFailedEventName: 'publishConnectionFailed',
222
+ blockReconnect: false,
223
+ };
224
+ this.consumeConnection = {
225
+ connection: null,
226
+ creatingConnection: false,
227
+ connectionCreatedEventName: 'consumeConnectionCreated',
228
+ connectionFailedEventName: 'consumeConnectionFailed',
229
+ blockReconnect: false,
230
+ };
212
231
  this.creatingConnection = false;
213
232
  this.exchanges = {};
214
233
  this.queues = {};
@@ -234,9 +253,22 @@ class RabbitMq implements IAfRabbitMq {
234
253
 
235
254
  // TODO: [QUORUM-PHASE-3] Delete the old properties that we use for the old consumers and publishers
236
255
  this.oldEm = new EventEmitter();
237
- this.oldChannel = null;
256
+ this.oldPublishChannel = null;
238
257
  this.oldPublishChannelSetupPromise = null;
239
- this.oldConnection = null;
258
+ this.oldPublishConnection = {
259
+ connection: null,
260
+ creatingConnection: false,
261
+ connectionCreatedEventName: 'publishConnectionCreated',
262
+ connectionFailedEventName: 'publishConnectionFailed',
263
+ blockReconnect: false,
264
+ };
265
+ this.oldConsumeConnection = {
266
+ connection: null,
267
+ creatingConnection: false,
268
+ connectionCreatedEventName: 'consumeConnectionCreated',
269
+ connectionFailedEventName: 'consumeConnectionFailed',
270
+ blockReconnect: false,
271
+ };
240
272
  this.oldCreatingConnection = false;
241
273
  this.oldExchanges = {};
242
274
  this.oldQueues = {};
@@ -374,30 +406,37 @@ class RabbitMq implements IAfRabbitMq {
374
406
  }
375
407
  }
376
408
 
377
- async getConnection() {
409
+ async getConnection(connection: ConnectionData) {
378
410
  return new Promise<AmqpConnectionManager>(async (resolve, reject) => {
379
- if (this.blockReconnect) {
411
+ const {
412
+ connection: connectionLocal,
413
+ creatingConnection,
414
+ connectionCreatedEventName,
415
+ connectionFailedEventName,
416
+ blockReconnect,
417
+ } = connection;
418
+ if (blockReconnect) {
380
419
  debug('rabbit: block reconnect');
381
420
  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
382
421
  // @ts-ignore
383
422
  return resolve();
384
423
  }
385
- if (this.connection !== null) {
386
- if (this.options?.disableReconnect || this.connection?.isConnected()) {
424
+ if (connectionLocal !== null) {
425
+ if (this.options?.disableReconnect || connectionLocal?.isConnected()) {
387
426
  debug('rabbit: connection - is connected');
388
427
  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
389
428
  // @ts-ignore
390
- return resolve(this.connection);
429
+ return resolve(connectionLocal);
391
430
  }
392
431
  debug('rabbit: connection - reconnecting');
393
432
  }
394
- if (this.creatingConnection) {
433
+ if (creatingConnection) {
395
434
  debug('rabbit: creating connection emi');
396
- this.em.once(CONNECTION_CREATED_CONST, resolve);
397
- this.em.once(CONNECTION_FAILED_CONST, reject);
435
+ this.em.once(connectionCreatedEventName, resolve);
436
+ this.em.once(connectionFailedEventName, reject);
398
437
  return;
399
438
  }
400
- this.creatingConnection = true;
439
+ connection.creatingConnection = true;
401
440
  let isResolved = false;
402
441
 
403
442
  // It is import to use it as a function and not as a variable
@@ -413,61 +452,63 @@ class RabbitMq implements IAfRabbitMq {
413
452
  };
414
453
 
415
454
  const defaultUrls = findServers();
416
- const connection: AmqpConnectionManager = await connect(defaultUrls, {
455
+ const newConnection: AmqpConnectionManager = await connect(defaultUrls, {
417
456
  findServers,
418
457
  });
419
458
 
420
- this.connection = connection;
421
- this.connection.on('error', (err) => {
459
+ connection.connection = newConnection;
460
+ newConnection.on('error', (err) => {
422
461
  logger.error('rabbit: connection error', { err });
423
462
  if (!isResolved) {
424
463
  isResolved = true;
425
464
  reject(err);
426
- this.em.emit(CONNECTION_FAILED_CONST, err);
465
+ this.em.emit(connectionFailedEventName, err);
427
466
  }
428
467
  });
429
468
 
430
- this.connection.on('connectFailed', (err) => {
469
+ newConnection.on('connectFailed', (err) => {
431
470
  this.consumersTags = [];
432
471
  logger.error('rabbit: connection connectFailed', { err, advice: 'Check if the vhost exist', vhost: this.vhost });
433
472
  if (!isResolved) {
434
473
  isResolved = true;
435
474
  reject(err);
436
- this.em.emit(CONNECTION_FAILED_CONST, err);
475
+ this.em.emit(connectionFailedEventName, err);
437
476
  }
438
477
  });
439
478
 
440
- this.connection.on('disconnect', ({ err }) => {
441
- // this.channel = null;
479
+ newConnection.on('disconnect', ({ err }) => {
480
+ // this.publishChannel = null;
442
481
  this.consumersTags = [];
443
482
  debug('rabbit: connection closed');
444
483
  if (this.options?.disableReconnect) {
445
484
  logger.error(`${this.DISCONNECT_MSG}${err && ` - ${err}`}`);
446
- this.blockReconnect = true;
485
+ connection.blockReconnect = true;
447
486
  } else {
448
487
  logger.error(`${this.RECONNECT_MSG}${err && ` - ${err}`}`);
449
488
  }
450
489
  });
451
490
 
452
- this.connection.once('connect', async () => {
491
+ newConnection.once('connect', async () => {
453
492
  debug('rabbit: connection established');
454
- this.creatingConnection = false;
455
- this.em.emit(CONNECTION_CREATED_CONST, connection);
493
+ connection.creatingConnection = false;
494
+ this.em.emit(connectionCreatedEventName, connection);
456
495
  isResolved = true;
457
- resolve(connection);
496
+ resolve(newConnection);
458
497
  });
459
498
  });
460
499
  }
461
500
 
462
- async getNewChannel({ name = rand().toString(), onClose = null, options = {} }: newChannelOpts = {}) {
463
- let connection!: AmqpConnectionManager;
501
+ async getNewChannel({
502
+ name = rand().toString(), onClose = null, options = {}, connection,
503
+ }: newChannelOpts) {
504
+ let localConnection!: AmqpConnectionManager;
464
505
  try {
465
- connection = await this.getConnection();
506
+ localConnection = await this.getConnection(connection);
466
507
  } catch (e) {
467
508
  logger.error(`rabbit: error on get connection for new channel ${name} `, { e });
468
509
  throw e;
469
510
  }
470
- const channel = connection.createChannel({ ...options });
511
+ const channel = localConnection.createChannel({ ...options });
471
512
  once(channel, 'close').then((args) => {
472
513
  logger.error(`rabbit: channel ${name} closed`);
473
514
  onClose?.(args);
@@ -482,19 +523,21 @@ class RabbitMq implements IAfRabbitMq {
482
523
  }
483
524
  }
484
525
 
485
- async assertChannel({ force = false } : assertChannelOpts = {}): Promise<ChannelWrapper> {
526
+ async assertChannel({ force = false, connection }: assertChannelOpts): Promise<ChannelWrapper> {
486
527
  if (!this.publishChannelSetupPromise) {
487
528
  this.publishChannelSetupPromise = new Promise<ChannelWrapper>(async (resolve, reject) => {
488
- if (this.channel && !force) {
489
- return resolve(this.channel);
529
+ if (this.publishChannel && !force) {
530
+ return resolve(this.publishChannel);
490
531
  }
491
532
 
492
533
  try {
493
- const channel = await this.getNewChannel({});
534
+ const channel = await this.getNewChannel({ connection });
494
535
  channel.on('error', (err) => {
495
536
  logger.error('rabbit: channel error', { err });
496
537
  });
497
- this.channel = channel;
538
+ if (this.publishConnection === connection) {
539
+ this.publishChannel = channel;
540
+ }
498
541
  resolve(channel);
499
542
  } catch (e) {
500
543
  reject(e);
@@ -504,8 +547,8 @@ class RabbitMq implements IAfRabbitMq {
504
547
  return this.publishChannelSetupPromise;
505
548
  }
506
549
 
507
- async assertExchange(exchangeName: string, options?: any) {
508
- const channel: ChannelWrapper = await this.assertChannel();
550
+ async assertExchange(exchangeName: string, connection: ConnectionData) {
551
+ const channel: ChannelWrapper = await this.assertChannel({ connection });
509
552
 
510
553
  if (this.exchanges[exchangeName]) {
511
554
  delete this.assertExchangePromises[exchangeName];
@@ -524,7 +567,7 @@ class RabbitMq implements IAfRabbitMq {
524
567
  // TODO: [QUORUM-PHASE-2] Change the implementation to the new one
525
568
  async getQueueLength(queue: string) {
526
569
  RabbitMq.validateName('queue', queue);
527
- const { oldChannel: channel } = this;
570
+ const { oldPublishChannel: channel } = this;
528
571
  if (!channel) {
529
572
  throw new RabbitError('channel is not defined');
530
573
  }
@@ -532,9 +575,9 @@ class RabbitMq implements IAfRabbitMq {
532
575
  return channel?.checkQueue(queue);
533
576
  }
534
577
 
535
- private async deleteQueue(queue: string) {
578
+ private async deleteQueue(queue: string, connection: ConnectionData) {
536
579
  RabbitMq.validateName('queue', queue);
537
- const channel: ChannelWrapper = await this.assertChannel();
580
+ const channel: ChannelWrapper = await this.assertChannel({ connection });
538
581
  logger.info('rabbit: deleting queue', { queue });
539
582
  const deleteQueueRes = await channel.deleteQueue(queue);
540
583
  debug('queue deleted', deleteQueueRes);
@@ -543,13 +586,14 @@ class RabbitMq implements IAfRabbitMq {
543
586
 
544
587
  // TODO: [QUORUM-PHASE-2] Change the implementation to the new one
545
588
  async bindQueue(queue: string, exchange: string) {
546
- const channel: ChannelWrapper = await this.assertChannelOld();
589
+ const channel: ChannelWrapper = await this.assertChannelOld({ connection: this.oldPublishConnection });
547
590
  await channel.addSetup((setupChannel: ConfirmChannel) => setupChannel.bindQueue(queue, exchange, ''));
548
591
  return channel.bindQueue(queue, exchange, '');
549
592
  }
550
593
 
551
594
  async setupQueue(queueName: string, options?: Options.AssertQueue): Promise<Replies.AssertQueue> {
552
595
  let queue: Replies.AssertQueue;
596
+ const connection = this.publishConnection;
553
597
  const localeOptions = {
554
598
  ...options,
555
599
  durable: true,
@@ -560,7 +604,7 @@ class RabbitMq implements IAfRabbitMq {
560
604
  },
561
605
  };
562
606
  try {
563
- const channel: ChannelWrapper = await this.assertChannel();
607
+ const channel: ChannelWrapper = await this.assertChannel({ connection });
564
608
  debug('assertQueue->channel.addSetup', { queueName });
565
609
  await channel.addSetup(async (setupChannel: ConfirmChannel) => {
566
610
  await setupChannel.assertQueue(queueName, localeOptions);
@@ -571,8 +615,8 @@ class RabbitMq implements IAfRabbitMq {
571
615
  logger.error('rabbit: assertQueue error', { queueName, options, error: e });
572
616
  if (!this.options?.dontRetryAssert) {
573
617
  debug('retrying assertQueue', { queueName });
574
- const channel = await this.assertChannel({ force: true });
575
- await this.deleteQueue(queueName);
618
+ const channel = await this.assertChannel({ force: true, connection });
619
+ await this.deleteQueue(queueName, connection);
576
620
 
577
621
  debug('retrying assertQueue->channel.addSetup', { queueName });
578
622
  await channel.addSetup((setupChannel: ConfirmChannel) => setupChannel.assertQueue(queueName, localeOptions));
@@ -685,7 +729,7 @@ class RabbitMq implements IAfRabbitMq {
685
729
  }
686
730
  logger.info(`rabbit: Consuming with lock from queue ${queue} with lockTimeout: ${lockTimeout}ms`);
687
731
  }
688
- const channel = await this.getNewChannel({});
732
+ const channel = await this.getNewChannel({ connection: this.consumeConnection });
689
733
  return channel.addSetup(async (confirmChannel: ConfirmChannel) => {
690
734
  const q = await this.assertQueue(queue, optionsWithDefaults);
691
735
  await confirmChannel.prefetch(limit, false);
@@ -785,7 +829,10 @@ class RabbitMq implements IAfRabbitMq {
785
829
  if (options?.isQuorumQueue !== false) {
786
830
  await this.assertVHost();
787
831
  await this.saveConsumer(queue, callback, options);
788
- const channel: ChannelWrapper = await this.getNewChannel({ name: `consume-exchange-${exchange}-queue-${queue}` });
832
+ const channel: ChannelWrapper = await this.getNewChannel({
833
+ name: `consume-exchange-${exchange}-queue-${queue}`,
834
+ connection: this.consumeConnection,
835
+ });
789
836
 
790
837
  await channel.addSetup(async (c: ConfirmChannel) => {
791
838
  const assertExchange = await assertExchangeFanout(c, exchange);
@@ -805,7 +852,10 @@ class RabbitMq implements IAfRabbitMq {
805
852
 
806
853
  // TODO: [QUORUM-PHASE-3] Delete the old implementation
807
854
  await this.saveConsumerOld(queue, callback, options);
808
- const channelOld: ChannelWrapper = await this.getNewChannelOld({ name: `consume-exchange-${exchange}-queue-${queue}-old` });
855
+ const channelOld: ChannelWrapper = await this.getNewChannelOld({
856
+ name: `consume-exchange-${exchange}-queue-${queue}-old`,
857
+ connection: this.oldConsumeConnection,
858
+ });
809
859
  await channelOld.addSetup(async (c: ConfirmChannel) => {
810
860
  const assertExchange = await assertExchangeFanout(c, exchange);
811
861
  await c.assertQueue(queue);
@@ -827,8 +877,8 @@ class RabbitMq implements IAfRabbitMq {
827
877
  async publish(exchange: string, content: any, customHeaders?: any) : Promise<boolean> {
828
878
  return wrapSetImmediate(async () => {
829
879
  RabbitMq.validateName('exchange', exchange);
830
- const channel: ChannelWrapper = await this.assertChannelOld();
831
- await this.assertExchangeOld(exchange);
880
+ const channel: ChannelWrapper = await this.assertChannelOld({ connection: this.oldPublishConnection });
881
+ await this.assertExchangeOld(exchange, this.oldPublishConnection);
832
882
  await channel.publish(exchange, '',
833
883
  Buffer.from(JSON.stringify(content)),
834
884
  RabbitMq.getPublishOptions(customHeaders));
@@ -844,7 +894,7 @@ class RabbitMq implements IAfRabbitMq {
844
894
  customHeaders?: any,
845
895
  ): Promise<boolean | undefined> {
846
896
  try {
847
- await this.assertChannelOld();
897
+ await this.assertChannelOld({ connection: this.oldPublishConnection });
848
898
  } catch (e) {
849
899
  logger.error(`rabbit sendToQueue: failed to send assert channel when sending to queue ${queue}`, { e });
850
900
  throw e;
@@ -859,7 +909,7 @@ class RabbitMq implements IAfRabbitMq {
859
909
  }
860
910
 
861
911
  try {
862
- const res = await this.oldChannel?.sendToQueue(queue,
912
+ const res = await this.oldPublishChannel?.sendToQueue(queue,
863
913
  Buffer.from(JSON.stringify(content)),
864
914
  RabbitMq.getPublishOptions(customHeaders));
865
915
  debug(`rabbit: sending to queue ${queue}`, { res });
@@ -871,61 +921,17 @@ class RabbitMq implements IAfRabbitMq {
871
921
  }
872
922
  }
873
923
 
874
- async sendToCeleryQueue(
875
- data: TaskData,
876
- taskName: string,
877
- queueName: string,
878
- ): Promise<boolean | undefined> {
879
- const taskId = randomUUID();
880
-
881
- // Celery-compatible message body
882
- const taskPayload = {
883
- task: taskName,
884
- id: taskId,
885
- args: [data],
886
- kwargs: {},
887
- retries: 0,
888
- eta: null,
889
- };
890
-
891
- // Celery-compatible AMQP headers
892
- const publishOptions = {
893
- contentType: 'application/json',
894
- contentEncoding: 'utf-8',
895
- deliveryMode: 2, // persistent
896
- headers: {
897
- lang: 'py',
898
- task: taskName,
899
- id: taskId,
900
- root_id: taskId,
901
- parent_id: null,
902
- group: null,
903
- retries: 0,
904
- eta: null,
905
- },
906
- };
907
-
908
- try {
909
- return await this.sendToQueue(queueName, taskPayload, undefined, publishOptions);
910
- } catch (e) {
911
- const isConnected = await this.isConnected();
912
- logger.error(
913
- `rabbit sendToQueue: failed to send to queue ${queueName}, isConnected: ${isConnected}`,
914
- { e },
915
- );
916
- throw e;
917
- }
918
- }
919
-
920
924
  // TODO: [QUORUM-PHASE-2] After changing the publish from old to new change from the old to the new implementation
921
925
  async isConnected() : Promise<boolean> {
922
- const connection = await this.getConnectionOld();
923
- const isConnected = connection.isConnected();
926
+ debug('rabbit: start is connected');
927
+ const consumeConnection = await this.getConnectionOld(this.oldConsumeConnection);
928
+ const publishConnection = await this.getConnectionOld(this.oldPublishConnection);
929
+ const isConnected = consumeConnection.isConnected() && publishConnection.isConnected();
924
930
  if (!isConnected) {
925
931
  logger.error('rabbit: isConnected - false');
926
932
  return false;
927
933
  }
928
- const channel: any = await this.assertChannelOld();
934
+ const channel: any = await this.assertChannelOld({ connection: this.oldPublishConnection });
929
935
  try {
930
936
  await Promise.all([
931
937
  channel.waitForConnect(),
@@ -935,7 +941,7 @@ class RabbitMq implements IAfRabbitMq {
935
941
  logger.error('rabbit: isConnected - false');
936
942
  return false;
937
943
  }
938
- logger.info('rabbit: isConnected - true');
944
+ logger.debug('rabbit: isConnected - true');
939
945
  return true;
940
946
  }
941
947
 
@@ -971,7 +977,7 @@ class RabbitMq implements IAfRabbitMq {
971
977
  }
972
978
  logger.info(`rabbit: Consuming with lock from queue ${queue} with lockTimeout: ${lockTimeout}ms`);
973
979
  }
974
- const channel = await this.getNewChannelOld({});
980
+ const channel = await this.getNewChannelOld({ connection: this.oldConsumeConnection });
975
981
  return channel.addSetup(async (confirmChannel: ConfirmChannel) => {
976
982
  const q = await this.assertQueueOld(queue, optionsWithDefaults);
977
983
  await confirmChannel.prefetch(limit, false);
@@ -1062,15 +1068,18 @@ class RabbitMq implements IAfRabbitMq {
1062
1068
  }
1063
1069
 
1064
1070
  // TODO: [QUORUM-PHASE-3] Delete all the function under this line (getNewChannelOld, getConnectionOld, assertQueueOld, setupQueueOld, saveConsumerOld)
1065
- async getNewChannelOld({ name = rand().toString(), onClose = null, options = {} }: newChannelOpts = {}) {
1066
- let connection!: AmqpConnectionManager;
1071
+ async getNewChannelOld({
1072
+ name = rand().toString(), onClose = null, options = {}, connection,
1073
+ }: newChannelOpts) {
1074
+ let localConnection!: AmqpConnectionManager;
1067
1075
  try {
1068
- connection = await this.getConnectionOld();
1076
+ localConnection = await this.getConnectionOld(connection);
1069
1077
  } catch (e) {
1070
1078
  logger.error(`rabbit: error on get connection for new channel ${name} `, { e });
1071
1079
  throw e;
1072
1080
  }
1073
- const channel = connection.createChannel({ ...options });
1081
+ debug('rabbit: getNewChannelOld', { localConnection });
1082
+ const channel = localConnection.createChannel({ ...options });
1074
1083
  once(channel, 'close').then((args) => {
1075
1084
  logger.error(`rabbit: channel ${name} closed`);
1076
1085
  onClose?.(args);
@@ -1085,30 +1094,38 @@ class RabbitMq implements IAfRabbitMq {
1085
1094
  }
1086
1095
  }
1087
1096
 
1088
- async getConnectionOld() {
1097
+ async getConnectionOld(connection: ConnectionData) {
1089
1098
  return new Promise<AmqpConnectionManager>(async (resolve, reject) => {
1090
- if (this.oldBlockReconnect) {
1099
+ const {
1100
+ connection: connectionLocal,
1101
+ creatingConnection,
1102
+ connectionCreatedEventName,
1103
+ connectionFailedEventName,
1104
+ blockReconnect,
1105
+ } = connection;
1106
+ debug('rabbit: getConnectionOld', { connectionLocal, creatingConnection, blockReconnect });
1107
+ if (blockReconnect) {
1091
1108
  debug('rabbit: block reconnect');
1092
1109
  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
1093
1110
  // @ts-ignore
1094
1111
  return resolve();
1095
1112
  }
1096
- if (this.oldConnection !== null) {
1097
- if (this.options?.disableReconnect || this.oldConnection?.isConnected()) {
1113
+ if (connectionLocal !== null) {
1114
+ if (this.options?.disableReconnect || connectionLocal?.isConnected()) {
1098
1115
  debug('rabbit: connection - is connected');
1099
1116
  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
1100
1117
  // @ts-ignore
1101
- return resolve(this.oldConnection);
1118
+ return resolve(connectionLocal);
1102
1119
  }
1103
1120
  debug('rabbit: connection - reconnecting');
1104
1121
  }
1105
- if (this.oldCreatingConnection) {
1122
+ if (creatingConnection) {
1106
1123
  debug('rabbit: creating connection emi');
1107
- this.oldEm.once(CONNECTION_CREATED_CONST, resolve);
1108
- this.oldEm.once(CONNECTION_FAILED_CONST, reject);
1124
+ this.oldEm.once(connectionCreatedEventName, resolve);
1125
+ this.oldEm.once(connectionFailedEventName, reject);
1109
1126
  return;
1110
1127
  }
1111
- this.oldCreatingConnection = true;
1128
+ connection.creatingConnection = true;
1112
1129
  let isResolved = false;
1113
1130
 
1114
1131
  // It is import to use it as a function and not as a variable
@@ -1125,47 +1142,47 @@ class RabbitMq implements IAfRabbitMq {
1125
1142
  };
1126
1143
 
1127
1144
  const defaultUrls = findServers();
1128
- const connection: AmqpConnectionManager = await connect(defaultUrls, {
1145
+ const newConnection: AmqpConnectionManager = await connect(defaultUrls, {
1129
1146
  findServers,
1130
1147
  });
1131
1148
 
1132
- this.oldConnection = connection;
1133
- this.oldConnection.on('error', (err) => {
1149
+ connection.connection = newConnection;
1150
+ newConnection.on('error', (err) => {
1134
1151
  logger.error('rabbit: connection error', { err });
1135
1152
  if (!isResolved) {
1136
1153
  isResolved = true;
1137
1154
  reject(err);
1138
- this.oldEm.emit(CONNECTION_FAILED_CONST, err);
1155
+ this.oldEm.emit(connectionFailedEventName, err);
1139
1156
  }
1140
1157
  });
1141
1158
 
1142
- this.oldConnection.on('connectFailed', (err) => {
1159
+ newConnection.on('connectFailed', (err) => {
1143
1160
  this.oldConsumersTags = [];
1144
1161
  logger.error('rabbit: connection connectFailed', { err });
1145
1162
  if (!isResolved) {
1146
1163
  isResolved = true;
1147
1164
  reject(err);
1148
- this.oldEm.emit(CONNECTION_FAILED_CONST, err);
1165
+ this.oldEm.emit(connectionFailedEventName, err);
1149
1166
  }
1150
1167
  });
1151
1168
 
1152
- this.oldConnection.on('disconnect', ({ err }) => {
1169
+ newConnection.on('disconnect', ({ err }) => {
1153
1170
  this.oldConsumersTags = [];
1154
1171
  debug('rabbit: connection closed');
1155
1172
  if (this.options?.disableReconnect) {
1156
1173
  logger.error(`${this.DISCONNECT_MSG}${err && ` - ${err}`}`);
1157
- this.oldBlockReconnect = true;
1174
+ connection.blockReconnect = true;
1158
1175
  } else {
1159
1176
  logger.error(`${this.RECONNECT_MSG}${err && ` - ${err}`}`);
1160
1177
  }
1161
1178
  });
1162
1179
 
1163
- this.oldConnection.once('connect', async () => {
1180
+ newConnection.once('connect', async () => {
1164
1181
  debug('rabbit: connection established');
1165
- this.oldCreatingConnection = false;
1166
- this.oldEm.emit(CONNECTION_CREATED_CONST, connection);
1182
+ connection.creatingConnection = false;
1183
+ this.oldEm.emit(connectionCreatedEventName, connection);
1167
1184
  isResolved = true;
1168
- resolve(connection);
1185
+ resolve(newConnection);
1169
1186
  });
1170
1187
  });
1171
1188
  }
@@ -1199,6 +1216,7 @@ class RabbitMq implements IAfRabbitMq {
1199
1216
 
1200
1217
  async setupQueueOld(queueName: string, options?: Options.AssertQueue): Promise<Replies.AssertQueue> {
1201
1218
  let queue: Replies.AssertQueue;
1219
+ const connection = this.oldPublishConnection;
1202
1220
  const shouldUseQuorum = RabbitMq.shouldUseQuorum(queueName);
1203
1221
  const localeOptions = {
1204
1222
  ...options,
@@ -1210,7 +1228,7 @@ class RabbitMq implements IAfRabbitMq {
1210
1228
  },
1211
1229
  };
1212
1230
  try {
1213
- const channel: ChannelWrapper = await this.assertChannelOld();
1231
+ const channel: ChannelWrapper = await this.assertChannelOld({ connection });
1214
1232
  debug('assertQueue->channel.addSetup', { queueName });
1215
1233
  await channel.addSetup((setupChannel: ConfirmChannel) => setupChannel.assertQueue(queueName, localeOptions));
1216
1234
  debug('assertQueue->channel.assertQueue', { queueName });
@@ -1219,8 +1237,8 @@ class RabbitMq implements IAfRabbitMq {
1219
1237
  logger.error('rabbit: assertQueue error', { queueName, options, error: e });
1220
1238
  if (!this.options?.dontRetryAssert) {
1221
1239
  debug('retrying assertQueue', { queueName });
1222
- const channel = await this.assertChannelOld({ force: true });
1223
- await this.deleteQueueOld(queueName);
1240
+ const channel = await this.assertChannelOld({ force: true, connection });
1241
+ await this.deleteQueueOld(queueName, connection);
1224
1242
 
1225
1243
  debug('retrying assertQueue->channel.addSetup', { queueName });
1226
1244
  await channel.addSetup((setupChannel: ConfirmChannel) => setupChannel.assertQueue(queueName, localeOptions));
@@ -1235,19 +1253,22 @@ class RabbitMq implements IAfRabbitMq {
1235
1253
  return queue;
1236
1254
  }
1237
1255
 
1238
- async assertChannelOld({ force = false } : assertChannelOpts = {}): Promise<ChannelWrapper> {
1256
+ async assertChannelOld({ force = false, connection }: assertChannelOpts): Promise<ChannelWrapper> {
1239
1257
  if (!this.oldPublishChannelSetupPromise) {
1240
1258
  this.oldPublishChannelSetupPromise = new Promise<ChannelWrapper>(async (resolve, reject) => {
1241
- if (this.oldChannel && !force) {
1242
- return resolve(this.oldChannel);
1259
+ if (this.oldPublishChannel && !force) {
1260
+ return resolve(this.oldPublishChannel);
1243
1261
  }
1244
1262
 
1245
1263
  try {
1246
- const channel = await this.getNewChannelOld({});
1264
+ const channel = await this.getNewChannelOld({ connection });
1247
1265
  channel.on('error', (err) => {
1248
1266
  logger.error('rabbit: channel error', { err });
1249
1267
  });
1250
- this.oldChannel = channel;
1268
+ if (this.oldPublishConnection === connection) {
1269
+ debug('rabbit: a new channel assigned to the oldPublishChannel', { connection });
1270
+ this.oldPublishChannel = channel;
1271
+ }
1251
1272
  resolve(channel);
1252
1273
  } catch (e) {
1253
1274
  reject(e);
@@ -1257,17 +1278,17 @@ class RabbitMq implements IAfRabbitMq {
1257
1278
  return this.oldPublishChannelSetupPromise;
1258
1279
  }
1259
1280
 
1260
- private async deleteQueueOld(queue: string) {
1281
+ private async deleteQueueOld(queue: string, connection: ConnectionData) {
1261
1282
  RabbitMq.validateName('queue', queue);
1262
- const channel: ChannelWrapper = await this.assertChannelOld();
1283
+ const channel: ChannelWrapper = await this.assertChannelOld({ connection });
1263
1284
  logger.info('rabbit: deleting queue', { queue });
1264
1285
  const deleteQueueRes = await channel.deleteQueue(queue);
1265
1286
  debug('queue deleted', deleteQueueRes);
1266
1287
  return deleteQueueRes;
1267
1288
  }
1268
1289
 
1269
- async assertExchangeOld(exchangeName: string, options?: any) {
1270
- const channel: ChannelWrapper = await this.assertChannelOld();
1290
+ async assertExchangeOld(exchangeName: string, connection: ConnectionData) {
1291
+ const channel: ChannelWrapper = await this.assertChannelOld({ connection });
1271
1292
 
1272
1293
  if (this.oldExchanges[exchangeName]) {
1273
1294
  delete this.oldAssertExchangePromises[exchangeName];