@autofleet/rabbit 3.2.2-2.beta-0 → 3.2.3

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.js CHANGED
@@ -10,7 +10,6 @@ const moment_1 = __importDefault(require("moment"));
10
10
  const redis_lock_1 = __importDefault(require("redis-lock"));
11
11
  const amqp_connection_manager_1 = require("amqp-connection-manager");
12
12
  const zehut_1 = require("@autofleet/zehut");
13
- const node_crypto_1 = require("node:crypto");
14
13
  const logger_1 = __importDefault(require("./logger"));
15
14
  const rabbitError_1 = __importDefault(require("./lib/rabbitError"));
16
15
  const redis_1 = __importDefault(require("./lib/redis"));
@@ -18,43 +17,10 @@ const utils_1 = require("./lib/utils");
18
17
  const consts_1 = require("./lib/consts");
19
18
  const types_1 = require("./lib/types");
20
19
  // const debug = nodeDebug('af-rabbitmq')
21
- const debug = logger_1.default.debug.bind(logger_1.default);
20
+ const debug = logger_1.default.info;
22
21
  const PUBLISH_TIMEOUT = 1000 * 10;
23
22
  const HEARTBEAT = '60';
24
23
  class RabbitMq {
25
- static parseMsg(msg) {
26
- let { content } = msg;
27
- content = content.toString();
28
- try {
29
- content = JSON.parse(content);
30
- }
31
- catch (e) { }
32
- return {
33
- ...msg,
34
- content,
35
- };
36
- }
37
- static validateName(type, name) {
38
- if (!name || name === '') {
39
- throw new rabbitError_1.default(`error while using ${type} with no name`);
40
- }
41
- }
42
- static getPublishOptions(customHeaders = {}) {
43
- const trace = (0, zehut_1.getCurrentPayload)();
44
- const user = trace?.context?.get(consts_1.USER_OBJECT);
45
- const traceId = trace?.context?.get(consts_1.TRACING_HEADER);
46
- const outbreakTrace = zehut_1.outbreak.getCurrentContext();
47
- return {
48
- timestamp: (0, moment_1.default)().unix(),
49
- timeout: PUBLISH_TIMEOUT,
50
- headers: {
51
- creationTimestamp: (0, moment_1.default)().valueOf(),
52
- ...customHeaders,
53
- [consts_1.USER_TRACING_HEADER]: user?.id,
54
- [consts_1.TRACING_HEADER]: traceId || outbreakTrace?.context?.get(consts_1.TRACING_HEADER),
55
- },
56
- };
57
- }
58
24
  constructor(options, redisConfig) {
59
25
  this.DISCONNECT_MSG = 'rabbit: connection disconnect';
60
26
  this.RECONNECT_MSG = 'rabbit: connection disconnect - reconnecting';
@@ -73,7 +39,6 @@ class RabbitMq {
73
39
  };
74
40
  this.ack = (channel, msg, shouldUpdateRedisTimestamp = false, releaseLock = null) => async (userMsg) => {
75
41
  if (msg) {
76
- debug('rabbit acking message', { deliveryTag: msg.fields.deliveryTag });
77
42
  await channel.ack(msg);
78
43
  const { properties: { headers } } = msg;
79
44
  const timestamp = headers?.creationTimestamp;
@@ -106,30 +71,25 @@ class RabbitMq {
106
71
  : 1,
107
72
  });
108
73
  }
109
- debug('rabbit nacking message', { deliveryTag: msg.fields.deliveryTag });
110
74
  await channel.ack(msg);
111
75
  }
112
76
  else {
113
77
  logger_1.default.error('no channel or msg', {
78
+ channel: channel ? channel.name : '',
114
79
  msg,
115
80
  });
116
81
  }
117
82
  };
118
83
  this.em = new events_1.EventEmitter();
119
84
  this.channel = null;
120
- this.publishChannelSetupPromise = null;
121
- this.connectionsMap = {
122
- [types_1.ConnectionPurpose.Consume]: { connection: null, creatingConnection: false },
123
- [types_1.ConnectionPurpose.Publish]: { connection: null, creatingConnection: false },
124
- };
85
+ this.connection = null;
86
+ this.creatingConnection = false;
125
87
  this.exchanges = {};
126
88
  this.queues = {};
127
- this.queueSetupPromises = {};
128
- this.consumers = [];
129
89
  this.options = options;
130
- this.redisClient = redisConfig && (0, redis_1.default)(redisConfig);
90
+ this.redisClient = redisConfig && redis_1.default(redisConfig);
131
91
  if (this.redisClient) {
132
- this.redisLock = (0, util_1.promisify)((0, redis_lock_1.default)(this.redisClient));
92
+ this.redisLock = util_1.promisify(redis_lock_1.default(this.redisClient));
133
93
  }
134
94
  this.consumersTags = [];
135
95
  logger_1.default.info(`rabbit: [gracefully-shutdown] adding gracefully shutdown for process.pid ${process.pid}`);
@@ -142,31 +102,63 @@ class RabbitMq {
142
102
  });
143
103
  }
144
104
  }
145
- async getConnection(connectionPurpose) {
105
+ static parseMsg(msg) {
106
+ let { content } = msg;
107
+ content = content.toString();
108
+ try {
109
+ content = JSON.parse(content);
110
+ }
111
+ catch (e) { }
112
+ return {
113
+ ...msg,
114
+ content,
115
+ };
116
+ }
117
+ static validateName(type, name) {
118
+ if (!name || name === '') {
119
+ throw new rabbitError_1.default(`error while using ${type} with no name`);
120
+ }
121
+ }
122
+ static getPublishOptions(customHeaders = {}) {
123
+ const trace = zehut_1.getCurrentPayload();
124
+ const user = trace?.context?.get(consts_1.USER_OBJECT);
125
+ const traceId = trace?.context?.get(consts_1.TRACING_HEADER);
126
+ const outbreakTrace = zehut_1.outbreak.getCurrentContext();
127
+ return {
128
+ timestamp: moment_1.default().unix(),
129
+ timeout: PUBLISH_TIMEOUT,
130
+ headers: {
131
+ creationTimestamp: moment_1.default().valueOf(),
132
+ ...customHeaders,
133
+ [consts_1.USER_TRACING_HEADER]: user?.id,
134
+ [consts_1.TRACING_HEADER]: traceId || outbreakTrace?.context?.get(consts_1.TRACING_HEADER),
135
+ },
136
+ };
137
+ }
138
+ async getConnection() {
146
139
  return new Promise(async (resolve, reject) => {
147
- let { connection, creatingConnection } = this.connectionsMap[connectionPurpose];
148
140
  if (this.blockReconnect) {
149
141
  debug('rabbit: block reconnect');
150
142
  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
151
143
  // @ts-ignore
152
144
  return resolve();
153
145
  }
154
- if (connection !== null) {
155
- if (this.options?.disableReconnect || connection?.isConnected()) {
146
+ if (this.connection !== null) {
147
+ if (this.options?.disableReconnect || this.connection?.isConnected()) {
156
148
  debug('rabbit: connection - is connected');
157
149
  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
158
150
  // @ts-ignore
159
- return resolve(connection);
151
+ return resolve(this.connection);
160
152
  }
161
153
  debug('rabbit: connection - reconnecting');
162
154
  }
163
- if (creatingConnection) {
155
+ if (this.creatingConnection) {
164
156
  debug('rabbit: creating connection emi');
165
157
  this.em.once(consts_1.CONNECTION_CREATED_CONST, resolve);
166
158
  this.em.once(consts_1.CONNECTION_FAILED_CONST, reject);
167
159
  return;
168
160
  }
169
- this.connectionsMap[connectionPurpose].creatingConnection = true;
161
+ this.creatingConnection = true;
170
162
  let isResolved = false;
171
163
  // It is import to use it as a function and not as a variable
172
164
  // because of k8s changes the env variables
@@ -179,15 +171,11 @@ class RabbitMq {
179
171
  return [`amqp://${userName}:${password}@${host}?heartbeat=${HEARTBEAT}`];
180
172
  };
181
173
  const defaultUrls = findServers();
182
- const newConnection = await (0, amqp_connection_manager_1.connect)(defaultUrls, {
174
+ const connection = await amqp_connection_manager_1.connect(defaultUrls, {
183
175
  findServers,
184
176
  });
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) => {
177
+ this.connection = connection;
178
+ this.connection.on('error', (err) => {
191
179
  logger_1.default.error('rabbit: connection error', { err });
192
180
  if (!isResolved) {
193
181
  isResolved = true;
@@ -195,8 +183,7 @@ class RabbitMq {
195
183
  this.em.emit(consts_1.CONNECTION_FAILED_CONST, err);
196
184
  }
197
185
  });
198
- newConnection.on('connectFailed', (err) => {
199
- this.consumersTags = [];
186
+ this.connection.on('connectFailed', (err) => {
200
187
  logger_1.default.error('rabbit: connection connectFailed', { err });
201
188
  if (!isResolved) {
202
189
  isResolved = true;
@@ -204,9 +191,10 @@ class RabbitMq {
204
191
  this.em.emit(consts_1.CONNECTION_FAILED_CONST, err);
205
192
  }
206
193
  });
207
- newConnection.on('disconnect', ({ err }) => {
208
- this.consumersTags = [];
194
+ this.connection.on('disconnect', ({ err }) => {
209
195
  debug('rabbit: connection closed');
196
+ this.exchanges = {};
197
+ this.queues = {};
210
198
  if (this.options?.disableReconnect) {
211
199
  logger_1.default.error(`${this.DISCONNECT_MSG}${err && ` - ${err}`}`);
212
200
  this.blockReconnect = true;
@@ -215,99 +203,95 @@ class RabbitMq {
215
203
  logger_1.default.error(`${this.RECONNECT_MSG}${err && ` - ${err}`}`);
216
204
  }
217
205
  });
218
- newConnection.once('connect', async () => {
206
+ this.connection.once('connect', async () => {
219
207
  debug('rabbit: connection established');
220
- this.connectionsMap[connectionPurpose].creatingConnection = false;
221
- this.em.emit(consts_1.CONNECTION_CREATED_CONST, newConnection);
208
+ await this.loadConsumers();
209
+ this.creatingConnection = false;
210
+ this.em.emit(consts_1.CONNECTION_CREATED_CONST, connection);
222
211
  isResolved = true;
223
- resolve(newConnection);
212
+ resolve(connection);
224
213
  });
225
214
  });
226
215
  }
227
- async getNewChannel({ name = (0, utils_1.rand)().toString(), onClose = null, options = {}, connectionPurpose = types_1.ConnectionPurpose.Consume, }) {
228
- let connection;
229
- try {
230
- connection = await this.getConnection(connectionPurpose);
231
- }
232
- catch (e) {
233
- logger_1.default.error(`rabbit: error on get connection for new channel ${name} `, { e });
234
- throw e;
235
- }
236
- if (!connection) {
237
- throw new Error(`rabbit: couldnt get connection for new channel ${name}`);
238
- }
239
- const channel = connection.createChannel({ ...options });
240
- (0, events_1.once)(channel, 'close').then((args) => {
241
- logger_1.default.error(`rabbit: channel ${name} closed`);
242
- onClose?.(args);
243
- });
244
- try {
245
- await (0, events_1.once)(channel, 'connect');
246
- debug(`rabbit: channel ${name} CONNECTED`);
247
- return channel;
248
- }
249
- catch (err) {
250
- logger_1.default.error(`rabbit: channel error ${name} error`, { err });
251
- throw err;
252
- }
253
- }
254
- async assertChannel({ force = false, connectionPurpose = types_1.ConnectionPurpose.Consume }) {
255
- if (!this.publishChannelSetupPromise) {
256
- this.publishChannelSetupPromise = new Promise(async (resolve, reject) => {
257
- if (this.channel && !force) {
258
- return resolve(this.channel);
259
- }
260
- try {
261
- const channel = await this.getNewChannel({ connectionPurpose });
262
- channel.on('error', (err) => {
263
- logger_1.default.error('rabbit: channel error', { err });
264
- });
265
- this.channel = channel;
266
- resolve(channel);
216
+ async getNewChannel({ name = utils_1.rand().toString(), onClose = null } = {}) {
217
+ return new Promise(async (resolve, reject) => {
218
+ const connection = await this.getConnection();
219
+ const channel = connection.createChannel({});
220
+ let isResolved = false;
221
+ channel.on('error', (err) => {
222
+ logger_1.default.error(`rabbit: channel ${name} error`, { err });
223
+ if (!isResolved) {
224
+ isResolved = true;
225
+ reject(err);
267
226
  }
268
- catch (e) {
269
- reject(e);
227
+ });
228
+ channel.on('close', (...args) => {
229
+ logger_1.default.error(`rabbit: channel ${name} closed`, { args });
230
+ if (onClose) {
231
+ onClose(args);
270
232
  }
271
233
  });
272
- }
273
- return this.publishChannelSetupPromise;
234
+ channel.once('connect', () => {
235
+ debug(`rabbit: channel ${name} CONNECTED`);
236
+ isResolved = true;
237
+ resolve(channel);
238
+ });
239
+ });
240
+ }
241
+ async assertChannel({ force = false } = {}) {
242
+ return new Promise(async (resolve, reject) => {
243
+ if (this.channel && !force) {
244
+ return resolve(this.channel);
245
+ }
246
+ try {
247
+ const channel = await this.getNewChannel({});
248
+ channel.on('error', (err) => {
249
+ logger_1.default.error('rabbit: channel error', { err });
250
+ });
251
+ this.channel = channel;
252
+ resolve(channel);
253
+ }
254
+ catch (e) {
255
+ reject(e);
256
+ }
257
+ });
274
258
  }
275
259
  async assertExchange(exchangeName, options) {
276
- const channel = await this.assertChannel({ connectionPurpose: options.connectionPurpose });
260
+ const channel = await this.assertChannel();
277
261
  if (this.exchanges[exchangeName]) {
278
262
  return this.exchanges[exchangeName];
279
263
  }
280
- const exchange = await (0, utils_1.assertExchangeFanout)(channel, exchangeName);
264
+ const exchange = await utils_1.assertExchangeFanout(channel, exchangeName);
281
265
  this.exchanges[exchangeName] = exchange;
282
266
  return exchange;
283
267
  }
284
- async getQueueLength(queue, connectionPurpose = types_1.ConnectionPurpose.Consume) {
268
+ async getQueueLength(queue) {
285
269
  RabbitMq.validateName('queue', queue);
286
- let { connection } = this.connectionsMap[connectionPurpose];
287
- const { channel } = this;
288
- if (!channel) {
289
- throw new Error('channel is not defined');
290
- }
291
- debug('rabbit: getting queue length', { queue, connected: connection?.isConnected() });
292
- return channel?.checkQueue(queue);
270
+ const channel = await this.assertChannel();
271
+ debug('rabbit: getting queue length', { queue, connected: this.connection?.isConnected() });
272
+ return channel.checkQueue(queue);
293
273
  }
294
- async deleteQueue(queue, connectionPurpose) {
274
+ async deleteQueue(queue) {
295
275
  RabbitMq.validateName('queue', queue);
296
- const channel = await this.assertChannel({ connectionPurpose });
276
+ const channel = await this.assertChannel();
297
277
  logger_1.default.info('rabbit: deleting queue', { queue });
298
278
  const deleteQueueRes = await channel.deleteQueue(queue);
299
279
  debug('queue deleted', deleteQueueRes);
300
280
  return deleteQueueRes;
301
281
  }
302
- async bindQueue(queue, exchange, connectionPurpose) {
303
- const channel = await this.assertChannel({ connectionPurpose });
282
+ async bindQueue(queue, exchange) {
283
+ const channel = await this.assertChannel();
304
284
  await channel.addSetup((setupChannel) => setupChannel.bindQueue(queue, exchange, ''));
305
285
  return channel.bindQueue(queue, exchange, '');
306
286
  }
307
- async setupQueue(queueName, connectionPurpose, options) {
308
- let queue;
287
+ async assertQueue(queueName, options) {
288
+ let queue = null;
289
+ RabbitMq.validateName('queue', queueName);
290
+ if (this.queues[queueName]) {
291
+ return this.queues[queueName];
292
+ }
309
293
  try {
310
- const channel = await this.assertChannel({ connectionPurpose });
294
+ const channel = await this.assertChannel();
311
295
  debug('assertQueue->channel.addSetup', { queueName });
312
296
  await channel.addSetup((setupChannel) => setupChannel.assertQueue(queueName, options));
313
297
  debug('assertQueue->channel.assertQueue', { queueName });
@@ -317,11 +301,11 @@ class RabbitMq {
317
301
  logger_1.default.error('rabbit: assertQueue error', { queueName, options, error: e });
318
302
  if (!this.options?.dontRetryAssert) {
319
303
  debug('retrying assertQueue', { queueName });
320
- const channel = await this.assertChannel({ force: true, connectionPurpose });
321
- await this.deleteQueue(queueName, connectionPurpose);
322
- debug('retrying assertQueue->channel.addSetup', { queueName });
304
+ const channel = await this.assertChannel({ force: true });
305
+ await this.deleteQueue(queueName);
306
+ debug('1assertQueue->channel.addSetup', { queueName });
323
307
  await channel.addSetup((setupChannel) => setupChannel.assertQueue(queueName, options));
324
- debug('retrying assertQueue->channel.assertQueue', { queueName });
308
+ debug('1assertQueue->channel.assertQueue', { queueName });
325
309
  queue = await channel.assertQueue(queueName, options);
326
310
  }
327
311
  else {
@@ -331,31 +315,25 @@ class RabbitMq {
331
315
  this.queues[queueName] = queueName;
332
316
  return queue;
333
317
  }
334
- async assertQueue(queueName, connectionPurpose, options) {
335
- RabbitMq.validateName('queue', queueName);
336
- if (this.queues[queueName]) {
337
- delete this.queueSetupPromises[queueName];
338
- return this.queues[queueName];
339
- }
340
- if (this.queueSetupPromises[queueName]) {
341
- return this.queueSetupPromises[queueName];
342
- }
343
- this.queueSetupPromises[queueName] = this.setupQueue(queueName, connectionPurpose, options);
344
- return this.queueSetupPromises[queueName];
345
- }
346
318
  saveConsumer(queue, callback, options) {
347
- const isConsumerExist = this.consumers.some((consumer) => consumer.queue === queue);
348
- if (!isConsumerExist) {
349
- logger_1.default.info(`rabbit: consumer: ${queue} saved in consumer array`);
350
- this.consumers.push({
351
- queue,
352
- callback,
353
- options,
354
- });
319
+ this.consumers.push({
320
+ queue,
321
+ callback,
322
+ options,
323
+ });
324
+ }
325
+ async loadConsumers() {
326
+ debug('rabbit: loading consumers', { consumers: this.consumers.length });
327
+ if (this.consumers.length > 0) {
328
+ await Promise.all(this.consumers.map((consumer) => this
329
+ .consumeFromRabbit(consumer.queue, consumer.callback, consumer.options)));
355
330
  }
356
331
  }
357
332
  async consume(queue, callback, options) {
358
- await this.consumeFromRabbit(queue, callback, options);
333
+ if (this.connection && !this.creatingConnection) {
334
+ this.consumeFromRabbit(queue, callback, options);
335
+ }
336
+ return this.saveConsumer(queue, callback, options);
359
337
  }
360
338
  async lockRedisIfNeeded(msg, options) {
361
339
  const { properties: { headers } } = msg;
@@ -374,8 +352,6 @@ class RabbitMq {
374
352
  async consumeFromRabbit(queue, callback, options) {
375
353
  const optionsWithDefaults = { ...consts_1.DEFAULT_OPTIONS, ...options };
376
354
  RabbitMq.validateName('queue', queue);
377
- this.saveConsumer(queue, callback, options);
378
- const uniqueId = (0, node_crypto_1.randomUUID)();
379
355
  const { limit, deadMessageTtl, useConsumeWithLock, lockTimeout, auditContext, enableRabbitTrace, } = optionsWithDefaults;
380
356
  if (useConsumeWithLock) {
381
357
  if (!this.redisLock) {
@@ -383,11 +359,11 @@ class RabbitMq {
383
359
  }
384
360
  logger_1.default.info(`rabbit: Consuming with lock from queue ${queue} with lockTimeout: ${lockTimeout}ms`);
385
361
  }
386
- const channel = await this.getNewChannel({ connectionPurpose: types_1.ConnectionPurpose.Consume });
387
- return channel.addSetup(async (confirmChannel) => {
388
- await confirmChannel.assertQueue(queue, options ? { messageTtl: options.messageTtl } : undefined);
389
- await confirmChannel.prefetch(limit, true);
390
- const { consumerTag } = await confirmChannel.consume(queue, async (msg) => {
362
+ const channel = await this.getNewChannel({ name: `consume-queue-${queue}` });
363
+ return channel.addSetup(async (c) => {
364
+ await c.assertQueue(queue, options ? { messageTtl: options.messageTtl } : undefined);
365
+ await c.prefetch(limit, true);
366
+ const { consumerTag } = await c.consume(queue, async (msg) => {
391
367
  if (!msg) {
392
368
  return null;
393
369
  }
@@ -395,7 +371,7 @@ class RabbitMq {
395
371
  const userId = msg.properties.headers[consts_1.USER_TRACING_HEADER];
396
372
  const parsedMessage = RabbitMq.parseMsg(msg);
397
373
  const releaseLock = await this.lockRedisIfNeeded(parsedMessage, optionsWithDefaults);
398
- const trace = (0, zehut_1.newTrace)(zehut_1.traceTypes.RABBIT);
374
+ const trace = zehut_1.newTrace(zehut_1.traceTypes.RABBIT);
399
375
  // setting also outbreak trace as part of legacy code
400
376
  const outbreakTrace = zehut_1.outbreak.newTrace(zehut_1.traceTypes.RABBIT);
401
377
  // enableRabbitTrace is a flag to protect from different flows that doesn't work with permission
@@ -403,13 +379,13 @@ class RabbitMq {
403
379
  if (userId && enableRabbitTrace) {
404
380
  try {
405
381
  await Promise.all([
406
- (0, zehut_1.createOrSetRabbitTrace)(trace, userId),
407
- (0, zehut_1.createOrSetRabbitTrace)(outbreakTrace, userId),
382
+ zehut_1.createOrSetRabbitTrace(trace, userId),
383
+ zehut_1.createOrSetRabbitTrace(outbreakTrace, userId),
408
384
  ]);
409
385
  }
410
386
  catch (e) {
411
387
  logger_1.default.error('rabbit: failed to setRabbitTrace', { userId, e });
412
- return this.nack(confirmChannel, queue, optionsWithDefaults, { messageTtl: deadMessageTtl }, msg, releaseLock)(msg);
388
+ await this.nack(channel, queue, optionsWithDefaults, { messageTtl: deadMessageTtl }, msg, releaseLock)(msg);
413
389
  }
414
390
  }
415
391
  if (traceId) {
@@ -422,30 +398,13 @@ class RabbitMq {
422
398
  const shouldConsume = await this.shouldConsumeMessageByTimestamp(parsedMessage);
423
399
  if (!shouldConsume) {
424
400
  await this.unlockRedisIfNeeded(releaseLock);
425
- return this.ack(confirmChannel, msg)(msg);
401
+ return this.ack(channel, msg)(msg);
426
402
  }
427
- let messageAcked = false;
428
- // setting the localAck function to be used in the callback
429
- const localAck = async () => {
430
- if (messageAcked) {
431
- return;
432
- }
433
- messageAcked = true;
434
- return this.ack(confirmChannel, msg, true, releaseLock)(msg);
435
- };
436
- const localNack = async (_, nackOptions = {}) => {
437
- if (messageAcked) {
438
- return;
439
- }
440
- debug('rabbit localNack', { messageAcked, uniqueId, deliveryTag: msg.fields.deliveryTag });
441
- messageAcked = true;
442
- return this.nack(confirmChannel, queue, optionsWithDefaults, { messageTtl: deadMessageTtl }, msg, releaseLock)(msg, nackOptions);
443
- };
444
403
  try {
445
- await callback(parsedMessage, localAck, localNack);
404
+ await callback(parsedMessage, this.ack(channel, msg, true, releaseLock), this.nack(channel, queue, optionsWithDefaults, { messageTtl: deadMessageTtl }, msg, releaseLock));
446
405
  }
447
406
  catch (e) {
448
- await localNack(msg);
407
+ await this.nack(channel, queue, optionsWithDefaults, { messageTtl: deadMessageTtl }, msg, releaseLock)(msg);
449
408
  }
450
409
  }, types_1.CONSUMER_DEFAULT_OPTIONS);
451
410
  if (!consumerTag) {
@@ -453,7 +412,7 @@ class RabbitMq {
453
412
  }
454
413
  else {
455
414
  logger_1.default.info(`rabbit: adding tag ${consumerTag} to the array.`);
456
- this.consumersTags.push([confirmChannel, consumerTag]);
415
+ this.consumersTags.push([c, consumerTag]);
457
416
  }
458
417
  });
459
418
  }
@@ -462,10 +421,9 @@ class RabbitMq {
462
421
  RabbitMq.validateName('exchange', exchange);
463
422
  RabbitMq.validateName('queue', queue);
464
423
  const { limit, deadMessageTtl } = optionsWithDefaults;
465
- await this.saveConsumer(queue, callback, options);
466
- const channel = await this.getNewChannel({ name: `consume - exchange - ${exchange} -queue - ${queue}`, connectionPurpose: types_1.ConnectionPurpose.Consume });
424
+ const channel = await this.getNewChannel({ name: `consume-exchange-${exchange}-queue-${queue}` });
467
425
  return channel.addSetup(async (c) => {
468
- const assertExchange = await (0, utils_1.assertExchangeFanout)(c, exchange);
426
+ const assertExchange = await utils_1.assertExchangeFanout(c, exchange);
469
427
  await c.assertQueue(queue);
470
428
  this.exchanges[exchange] = assertExchange;
471
429
  await c.prefetch(limit, true);
@@ -476,64 +434,36 @@ class RabbitMq {
476
434
  });
477
435
  }
478
436
  async publish(exchange, content, customHeaders) {
479
- return (0, utils_1.wrapSetImmediate)(async () => {
437
+ return utils_1.wrapSetImmediate(async () => {
480
438
  RabbitMq.validateName('exchange', exchange);
481
- const channel = await this.assertChannel({ connectionPurpose: types_1.ConnectionPurpose.Publish });
482
- await this.assertExchange(exchange, { connectionPurpose: types_1.ConnectionPurpose.Publish });
439
+ const channel = await this.assertChannel();
440
+ await this.assertExchange(exchange);
483
441
  await channel.publish(exchange, '', Buffer.from(JSON.stringify(content)), RabbitMq.getPublishOptions(customHeaders));
484
442
  });
485
443
  }
486
- async sendToQueue(queue, content, options, customHeaders) {
487
- try {
488
- await this.assertChannel({ connectionPurpose: types_1.ConnectionPurpose.Publish });
489
- }
490
- catch (e) {
491
- logger_1.default.error(`rabbit sendToQueue: failed to send assert channel when sending to queue ${queue}`, { e });
492
- throw e;
493
- }
494
- try {
495
- RabbitMq.validateName('queue', queue);
496
- await this.assertQueue(queue, types_1.ConnectionPurpose.Publish, options);
497
- }
498
- catch (e) {
499
- logger_1.default.error(`rabbit sendToQueue: failed to assert queue ${queue}`, { e });
500
- throw e;
501
- }
502
- try {
503
- const res = await this.channel?.sendToQueue(queue, Buffer.from(JSON.stringify(content)), RabbitMq.getPublishOptions(customHeaders));
504
- debug(`rabbit: sending to queue ${queue}`, { res });
505
- return res;
506
- }
507
- catch (e) {
508
- const isConnected = await this.isConnected(types_1.ConnectionPurpose.Publish);
509
- logger_1.default.error(`rabbit sendToQueue: failed to send to queue ${queue}, isConnected: ${isConnected}`, { e });
510
- throw e;
444
+ async sendToQueue(queue, content, options, customHeaders, isBlocking) {
445
+ const callback = async () => {
446
+ try {
447
+ RabbitMq.validateName('queue', queue);
448
+ await this.assertChannel();
449
+ await this.assertQueue(queue, options);
450
+ const res = await this.channel?.sendToQueue(queue, Buffer.from(JSON.stringify(content)), RabbitMq.getPublishOptions(customHeaders));
451
+ debug(`rabbit: sending to queue ${queue}`, { res });
452
+ return res;
453
+ }
454
+ catch (e) {
455
+ logger_1.default.error(`rabbit: failed to send to queue ${queue}`, { e });
456
+ throw e;
457
+ }
458
+ };
459
+ if (isBlocking) {
460
+ return callback();
511
461
  }
462
+ return utils_1.wrapSetImmediate(callback);
512
463
  }
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
- }
519
- const isConnected = connection.isConnected();
520
- if (!isConnected) {
521
- logger_1.default.error('rabbit: isConnected - false');
522
- return false;
523
- }
524
- const channel = await this.assertChannel({ connectionPurpose });
525
- try {
526
- await Promise.all([
527
- channel.waitForConnect(),
528
- ...this.consumers.map((c) => channel.checkQueue(c.queue)),
529
- ]);
530
- }
531
- catch (e) {
532
- logger_1.default.error('rabbit: isConnected - false');
533
- return false;
534
- }
535
- logger_1.default.info('rabbit: isConnected - true');
536
- return true;
464
+ async isConnected() {
465
+ const connection = await this.getConnection();
466
+ return connection.isConnected();
537
467
  }
538
468
  async gracefulShutdown(signal) {
539
469
  const tagsNumber = this.consumersTags.length;
@@ -1,4 +1,4 @@
1
- export type RedisConfig = {
1
+ export declare type RedisConfig = {
2
2
  host: string;
3
3
  port: number | undefined;
4
4
  prefix?: string;