@onlineapps/mq-client-core 1.0.7 → 1.0.10
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
|
@@ -151,16 +151,26 @@ class RabbitMQClient extends EventEmitter {
|
|
|
151
151
|
try {
|
|
152
152
|
// Ensure queue exists if publishing directly to queue and using default exchange
|
|
153
153
|
if (!exchange) {
|
|
154
|
-
// For infrastructure queues, they should already exist with specific arguments
|
|
154
|
+
// CRITICAL: For infrastructure queues, they should already exist with specific arguments from queueConfig
|
|
155
155
|
// Use queueChannel (regular channel) for checkQueue/assertQueue to avoid RPC reply queue issues
|
|
156
|
-
// If queue doesn't exist (404),
|
|
156
|
+
// If queue doesn't exist (404), we should NOT auto-create it - infrastructure queues must be created explicitly
|
|
157
|
+
// This prevents creating queues with wrong arguments (no TTL) which causes 406 errors later
|
|
157
158
|
try {
|
|
158
159
|
await this._queueChannel.checkQueue(queue);
|
|
159
160
|
// Queue exists - proceed to publish
|
|
160
161
|
} catch (checkErr) {
|
|
161
|
-
// If queue doesn't exist (404),
|
|
162
|
+
// If queue doesn't exist (404), this is an ERROR for infrastructure queues
|
|
163
|
+
// Infrastructure queues (workflow.*, registry.*) must be created explicitly with correct arguments
|
|
164
|
+
// We should NOT auto-create them here, as we don't have access to queueConfig in mq-client-core
|
|
162
165
|
if (checkErr.code === 404) {
|
|
166
|
+
// Check if this is an infrastructure queue
|
|
167
|
+
const isInfraQueue = queue.startsWith('workflow.') || queue.startsWith('registry.');
|
|
168
|
+
if (isInfraQueue) {
|
|
169
|
+
throw new Error(`Cannot publish to infrastructure queue ${queue}: queue does not exist. Infrastructure queues must be created explicitly with correct arguments (TTL, max-length, etc.) before publishing.`);
|
|
170
|
+
}
|
|
171
|
+
// For non-infrastructure queues, allow auto-creation with default options
|
|
163
172
|
const queueOptions = options.queueOptions || { durable: this._config.durable };
|
|
173
|
+
console.warn(`[RabbitMQClient] [mq-client-core] [PUBLISH] Auto-creating non-infrastructure queue ${queue} with default options (no TTL). This should be avoided for production.`);
|
|
164
174
|
await this._queueChannel.assertQueue(queue, queueOptions);
|
|
165
175
|
} else {
|
|
166
176
|
// Other error - rethrow
|
|
@@ -252,8 +262,25 @@ class RabbitMQClient extends EventEmitter {
|
|
|
252
262
|
|
|
253
263
|
console.log(`[RabbitMQClient] [mq-client-core] [CONSUMER] Asserting queue ${queue} before consume() at ${new Date().toISOString()}`);
|
|
254
264
|
console.log(`[RabbitMQClient] [mq-client-core] [CONSUMER] Queue options:`, JSON.stringify(queueOptions, null, 2));
|
|
265
|
+
console.log(`[RabbitMQClient] [mq-client-core] [CONSUMER] _queueChannel state: exists=${!!this._queueChannel}, closed=${this._queueChannel ? this._queueChannel.closed : 'N/A'}`);
|
|
255
266
|
|
|
267
|
+
// CRITICAL: Check if queue already exists with different arguments
|
|
268
|
+
// This can happen if sendToQueue() or amqplib's consume() auto-created it without TTL
|
|
256
269
|
try {
|
|
270
|
+
const queueInfo = await this._queueChannel.checkQueue(queue);
|
|
271
|
+
console.log(`[RabbitMQClient] [mq-client-core] [CONSUMER] Queue ${queue} already exists with arguments:`, JSON.stringify(queueInfo.messageCount !== undefined ? { messageCount: queueInfo.messageCount, consumerCount: queueInfo.consumerCount } : queueInfo));
|
|
272
|
+
// If queue exists, we need to check if arguments match
|
|
273
|
+
// Note: checkQueue() doesn't return arguments, so we'll try assertQueue() and catch 406
|
|
274
|
+
} catch (checkErr) {
|
|
275
|
+
if (checkErr.code === 404) {
|
|
276
|
+
console.log(`[RabbitMQClient] [mq-client-core] [CONSUMER] Queue ${queue} does not exist (404), will be created with options`);
|
|
277
|
+
} else {
|
|
278
|
+
console.warn(`[RabbitMQClient] [mq-client-core] [CONSUMER] checkQueue() failed for ${queue}:`, checkErr.message);
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
try {
|
|
283
|
+
console.log(`[RabbitMQClient] [mq-client-core] [CONSUMER] About to call assertQueue(${queue}, ${JSON.stringify(queueOptions)})`);
|
|
257
284
|
await this._queueChannel.assertQueue(queue, queueOptions);
|
|
258
285
|
console.log(`[RabbitMQClient] [mq-client-core] [CONSUMER] ✓ Queue ${queue} asserted successfully`);
|
|
259
286
|
} catch (assertErr) {
|
|
@@ -276,6 +303,26 @@ class RabbitMQClient extends EventEmitter {
|
|
|
276
303
|
this._channel.prefetch(prefetch);
|
|
277
304
|
}
|
|
278
305
|
|
|
306
|
+
// CRITICAL: Log before calling amqplib's consume()
|
|
307
|
+
// amqplib's consume() may internally call assertQueue() without parameters if queue doesn't exist
|
|
308
|
+
// This would create queue with default arguments (no TTL), causing 406 errors later
|
|
309
|
+
console.log(`[RabbitMQClient] [mq-client-core] [CONSUMER] About to call amqplib's channel.consume(${queue})`);
|
|
310
|
+
console.log(`[RabbitMQClient] [mq-client-core] [CONSUMER] ⚠ WARNING: amqplib's consume() may internally call assertQueue() WITHOUT parameters if queue doesn't exist`);
|
|
311
|
+
console.log(`[RabbitMQClient] [mq-client-core] [CONSUMER] ⚠ WARNING: We already asserted queue with correct parameters above - this should prevent auto-creation`);
|
|
312
|
+
|
|
313
|
+
// CRITICAL: Wrap amqplib's channel.consume() to intercept any internal assertQueue() calls
|
|
314
|
+
// This will help us identify if amqplib is creating the queue without TTL
|
|
315
|
+
const originalConsume = this._channel.consume.bind(this._channel);
|
|
316
|
+
const originalAssertQueue = this._channel.assertQueue.bind(this._channel);
|
|
317
|
+
|
|
318
|
+
// Intercept assertQueue() calls to log them
|
|
319
|
+
this._channel.assertQueue = async function(queueName, options) {
|
|
320
|
+
console.log(`[RabbitMQClient] [mq-client-core] [INTERCEPT] assertQueue() called for: ${queueName}`);
|
|
321
|
+
console.log(`[RabbitMQClient] [mq-client-core] [INTERCEPT] Options:`, JSON.stringify(options || {}, null, 2));
|
|
322
|
+
console.log(`[RabbitMQClient] [mq-client-core] [INTERCEPT] Stack trace:`, new Error().stack.split('\n').slice(1, 10).join('\n'));
|
|
323
|
+
return originalAssertQueue.call(this, queueName, options);
|
|
324
|
+
};
|
|
325
|
+
|
|
279
326
|
await this._channel.consume(
|
|
280
327
|
queue,
|
|
281
328
|
async (msg) => {
|