@onlineapps/mq-client-core 1.0.67 → 1.0.69

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@onlineapps/mq-client-core",
3
- "version": "1.0.67",
3
+ "version": "1.0.69",
4
4
  "description": "Core MQ client library for RabbitMQ - shared by infrastructure services and connectors",
5
5
  "main": "src/index.js",
6
6
  "scripts": {
package/src/BaseClient.js CHANGED
@@ -188,21 +188,9 @@ class BaseClient {
188
188
 
189
189
  try {
190
190
  const consumeStartTime = Date.now();
191
- await this._transport.consume(
192
- queue,
193
- async (msg) => {
194
- try {
195
- await messageHandler(msg);
196
- if (consumeOptions.noAck === false) {
197
- await this.ack(msg);
198
- }
199
- } catch (handlerErr) {
200
- // On handler error, nack with requeue: true
201
- await this.nack(msg, { requeue: true });
202
- }
203
- },
204
- consumeOptions
205
- );
191
+ // Delegate message lifecycle (ack/nack/requeue) to the transport layer.
192
+ // BaseClient only provides a broker-agnostic surface; transport decides how to handle handler errors.
193
+ await this._transport.consume(queue, async (msg) => messageHandler(msg), consumeOptions);
206
194
  const consumeEndTime = Date.now();
207
195
  console.log(`[BaseClient] [CONSUMER] ✓ consume() completed for queue: ${queue} (took ${consumeEndTime - consumeStartTime}ms)`);
208
196
  } catch (err) {
@@ -49,7 +49,7 @@ function createInfraLogger(service, layer) {
49
49
  class RabbitMQClient extends EventEmitter {
50
50
  /**
51
51
  * @param {Object} config
52
- * @param {string} config.host - AMQP URI or hostname (e.g., 'amqp://localhost:5672')
52
+ * @param {string} config.host - AMQP URI or hostname (e.g., 'amqp://127.0.0.1:5672')
53
53
  * @param {string} [config.queue] - Default queue name (optional; can be overridden per call)
54
54
  * @param {string} [config.exchange] - Default exchange (default: '')
55
55
  * @param {boolean} [config.durable] - Declare queues/exchanges as durable (default: true)
@@ -78,6 +78,7 @@ class RabbitMQClient extends EventEmitter {
78
78
 
79
79
  // Connection-level recovery
80
80
  this._reconnecting = false;
81
+ this._disconnecting = false;
81
82
  this._reconnectAttempts = 0;
82
83
  this._maxReconnectAttempts = this._config.maxReconnectAttempts || 10; // Max 10 attempts
83
84
  this._reconnectBaseDelay = this._config.reconnectBaseDelay || 1000; // Start with 1 second
@@ -432,11 +433,16 @@ class RabbitMQClient extends EventEmitter {
432
433
  : [{ ...rawTarget, heartbeat, clientProperties: { connection_name: connectionName } }];
433
434
 
434
435
  const connectPromise = amqp.connect(...connectArgs);
436
+ let connectTimeoutTimer = null;
435
437
  const timeoutPromise = new Promise((_, reject) => {
436
- setTimeout(() => reject(new Error('Connection timeout after 10 seconds')), 10000);
438
+ connectTimeoutTimer = setTimeout(() => reject(new Error('Connection timeout after 10 seconds')), 10000);
437
439
  });
438
440
  console.log('[RabbitMQClient] Starting connection race...');
439
441
  this._connection = await Promise.race([connectPromise, timeoutPromise]);
442
+ if (connectTimeoutTimer) {
443
+ clearTimeout(connectTimeoutTimer);
444
+ connectTimeoutTimer = null;
445
+ }
440
446
  console.log('[RabbitMQClient] Connection established');
441
447
  this._reconnectAttempts = 0; // Reset reconnect attempts on successful connection
442
448
 
@@ -447,6 +453,10 @@ class RabbitMQClient extends EventEmitter {
447
453
  });
448
454
 
449
455
  this._connection.on('close', () => {
456
+ if (this._disconnecting) {
457
+ console.log('[RabbitMQClient] Connection closed during disconnect (expected)');
458
+ return;
459
+ }
450
460
  console.warn('[RabbitMQClient] Connection closed unexpectedly - close handler STARTED');
451
461
  console.log(`[RabbitMQClient] Close handler: reconnectEnabled=${this._reconnectEnabled}, reconnecting=${this._reconnecting}`);
452
462
 
@@ -1019,6 +1029,7 @@ class RabbitMQClient extends EventEmitter {
1019
1029
  }
1020
1030
 
1021
1031
  async disconnect() {
1032
+ this._disconnecting = true;
1022
1033
  // Stop health monitoring
1023
1034
  this._stopHealthMonitoring();
1024
1035
 
@@ -1070,6 +1081,7 @@ class RabbitMQClient extends EventEmitter {
1070
1081
  this.emit('error', err);
1071
1082
  }
1072
1083
  }
1084
+ this._disconnecting = false;
1073
1085
  }
1074
1086
 
1075
1087
  /**
@@ -1788,6 +1800,9 @@ class RabbitMQClient extends EventEmitter {
1788
1800
  */
1789
1801
  _attachPublisherChannelHandlers(channel) {
1790
1802
  channel.on('error', async (err) => {
1803
+ if (this._disconnecting) {
1804
+ return;
1805
+ }
1791
1806
  const reason = `Publisher channel error: ${err.message} (code: ${err.code || 'unknown'})`;
1792
1807
  channel._closeReason = reason;
1793
1808
 
@@ -1819,6 +1834,9 @@ class RabbitMQClient extends EventEmitter {
1819
1834
  });
1820
1835
 
1821
1836
  channel.on('close', async () => {
1837
+ if (this._disconnecting) {
1838
+ return;
1839
+ }
1822
1840
  const reason = channel._closeReason || 'Publisher channel closed unexpectedly';
1823
1841
  console.warn(`[RabbitMQClient] [mq-client-core] ${reason} - will auto-recreate on next publish`);
1824
1842
  this._callChannelCloseHooks('publisher', channel, null, reason);
@@ -1848,6 +1866,9 @@ class RabbitMQClient extends EventEmitter {
1848
1866
  */
1849
1867
  _attachQueueChannelHandlers(channel) {
1850
1868
  channel.on('error', async (err) => {
1869
+ if (this._disconnecting) {
1870
+ return;
1871
+ }
1851
1872
  const reason = `Queue channel error: ${err.message} (code: ${err.code || 'unknown'})`;
1852
1873
  channel._closeReason = reason;
1853
1874
  console.warn(`[RabbitMQClient] [mq-client-core] ${reason}`);
@@ -1856,6 +1877,9 @@ class RabbitMQClient extends EventEmitter {
1856
1877
  });
1857
1878
 
1858
1879
  channel.on('close', async () => {
1880
+ if (this._disconnecting) {
1881
+ return;
1882
+ }
1859
1883
  const reason = channel._closeReason || 'Queue channel closed unexpectedly';
1860
1884
  console.warn(`[RabbitMQClient] [mq-client-core] ${reason} - will auto-recreate on next operation`);
1861
1885
  this._callChannelCloseHooks('queue', channel, null, reason);
@@ -1888,6 +1912,9 @@ class RabbitMQClient extends EventEmitter {
1888
1912
  */
1889
1913
  _attachConsumerChannelHandlers(channel) {
1890
1914
  channel.on('error', async (err) => {
1915
+ if (this._disconnecting) {
1916
+ return;
1917
+ }
1891
1918
  const reason = `Consumer channel error: ${err.message} (code: ${err.code || 'unknown'})`;
1892
1919
  channel._closeReason = reason;
1893
1920
  console.warn(`[RabbitMQClient] [mq-client-core] ${reason}`);
@@ -1897,6 +1924,9 @@ class RabbitMQClient extends EventEmitter {
1897
1924
  });
1898
1925
 
1899
1926
  channel.on('close', async () => {
1927
+ if (this._disconnecting) {
1928
+ return;
1929
+ }
1900
1930
  const reason = channel._closeReason || 'Consumer channel closed unexpectedly';
1901
1931
  console.warn(`[RabbitMQClient] [mq-client-core] ${reason} - will auto-recreate and re-register consumers`);
1902
1932
  this._callChannelCloseHooks('consumer', channel, null, reason);