@onlineapps/conn-infra-mq 1.1.30 → 1.1.32
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 +1 -1
- package/src/layers/QueueManager.js +47 -23
package/package.json
CHANGED
|
@@ -294,45 +294,69 @@ class QueueManager {
|
|
|
294
294
|
}
|
|
295
295
|
|
|
296
296
|
// CRITICAL: Use assertQueue directly - if queue exists with different args (406), that's OK
|
|
297
|
-
//
|
|
297
|
+
// BUT: 406 PRECONDITION-FAILED closes the channel in amqplib!
|
|
298
|
+
// Solution: Catch 406, recreate channel immediately, and continue
|
|
299
|
+
let queueCreated = false;
|
|
298
300
|
try {
|
|
299
|
-
// Check if channel is still open before each operation
|
|
300
|
-
if (!channel || channel.closed) {
|
|
301
|
-
console.error(`[QueueManager] DEBUG: Channel closed before creating ${queueName}`);
|
|
302
|
-
throw new Error(`Channel closed before creating ${queueName} - cannot continue`);
|
|
303
|
-
}
|
|
304
|
-
|
|
305
301
|
console.log(`[QueueManager] DEBUG: About to assertQueue ${queueName} with options:`, JSON.stringify(queueOptions, null, 2));
|
|
306
|
-
console.log(`[QueueManager] DEBUG: Channel state before assertQueue: closed=${channel.closed}`);
|
|
307
302
|
|
|
308
303
|
await channel.assertQueue(queueName, queueOptions);
|
|
309
304
|
|
|
310
|
-
console.log(`[QueueManager] DEBUG: assertQueue succeeded for ${queueName}
|
|
305
|
+
console.log(`[QueueManager] DEBUG: assertQueue succeeded for ${queueName}`);
|
|
311
306
|
queues[queueInfo.type] = queueName;
|
|
307
|
+
queueCreated = true;
|
|
312
308
|
console.info(`[QueueManager] ✓ Created business queue: ${queueName}`);
|
|
313
309
|
} catch (assertErr) {
|
|
314
310
|
console.error(`[QueueManager] DEBUG: assertQueue failed for ${queueName}:`, assertErr.message);
|
|
315
|
-
console.error(`[QueueManager] DEBUG: Error code: ${assertErr.code}
|
|
316
|
-
console.error(`[QueueManager] DEBUG: Stack trace:`, assertErr.stack);
|
|
311
|
+
console.error(`[QueueManager] DEBUG: Error code: ${assertErr.code}`);
|
|
317
312
|
|
|
318
|
-
// If
|
|
319
|
-
|
|
320
|
-
console.error(`[QueueManager] DEBUG: Channel was closed during assertQueue for ${queueName}`);
|
|
321
|
-
throw new Error(`Channel closed during assertQueue for ${queueName} - cannot create remaining queues`);
|
|
322
|
-
}
|
|
323
|
-
|
|
324
|
-
// If 406 PRECONDITION-FAILED, queue exists with different args - use it as-is
|
|
325
|
-
// CRITICAL: Do NOT use checkQueue() here - it closes channel on 404!
|
|
326
|
-
// If assertQueue() returned 406, queue exists (just with different args) - that's OK
|
|
313
|
+
// If 406 PRECONDITION-FAILED, queue exists with different args - channel is closed, recreate it IMMEDIATELY
|
|
314
|
+
// CRITICAL: amqplib closes channel on 406, so we MUST recreate it to continue
|
|
327
315
|
if (assertErr.code === 406) {
|
|
328
|
-
console.warn(`[QueueManager] Queue ${queueName} exists with different arguments,
|
|
316
|
+
console.warn(`[QueueManager] Queue ${queueName} exists with different arguments (406), channel will be closed. Recreating channel...`);
|
|
317
|
+
|
|
318
|
+
// Recreate channel IMMEDIATELY - 406 closes it synchronously
|
|
319
|
+
try {
|
|
320
|
+
// Wait a tiny bit for channel close event to propagate
|
|
321
|
+
await new Promise(resolve => setImmediate(resolve));
|
|
322
|
+
channel = await transport._connection.createChannel();
|
|
323
|
+
transport.queueChannel = channel;
|
|
324
|
+
console.log(`[QueueManager] DEBUG: Channel recreated after 406 for ${queueName}`);
|
|
325
|
+
} catch (recreateErr) {
|
|
326
|
+
throw new Error(`Failed to recreate channel after 406 for ${queueName}: ${recreateErr.message}`);
|
|
327
|
+
}
|
|
328
|
+
|
|
329
329
|
// Queue exists (just with different args) - accept it
|
|
330
330
|
queues[queueInfo.type] = queueName;
|
|
331
|
+
queueCreated = true;
|
|
331
332
|
} else {
|
|
332
|
-
// Other error -
|
|
333
|
-
|
|
333
|
+
// Other error - check if it's a channel closed error
|
|
334
|
+
if (assertErr.message && assertErr.message.includes('Channel closed')) {
|
|
335
|
+
console.error(`[QueueManager] DEBUG: Channel was closed during assertQueue for ${queueName}, recreating...`);
|
|
336
|
+
// Try to recreate channel
|
|
337
|
+
try {
|
|
338
|
+
await new Promise(resolve => setImmediate(resolve));
|
|
339
|
+
channel = await transport._connection.createChannel();
|
|
340
|
+
transport.queueChannel = channel;
|
|
341
|
+
console.log(`[QueueManager] DEBUG: Channel recreated after channel closed error for ${queueName}`);
|
|
342
|
+
} catch (recreateErr) {
|
|
343
|
+
throw new Error(`Channel closed during assertQueue for ${queueName} and failed to recreate: ${recreateErr.message}`);
|
|
344
|
+
}
|
|
345
|
+
// Retry assertQueue with new channel (but only if it's not 406)
|
|
346
|
+
if (assertErr.code !== 406) {
|
|
347
|
+
throw new Error(`Failed to create business queue ${queueName}: ${assertErr.message}`);
|
|
348
|
+
}
|
|
349
|
+
} else {
|
|
350
|
+
// Other error - critical, cannot continue
|
|
351
|
+
throw new Error(`Failed to create business queue ${queueName}: ${assertErr.message}`);
|
|
352
|
+
}
|
|
334
353
|
}
|
|
335
354
|
}
|
|
355
|
+
|
|
356
|
+
// Verify queue was created/confirmed
|
|
357
|
+
if (!queueCreated) {
|
|
358
|
+
throw new Error(`Failed to create or confirm business queue ${queueName}`);
|
|
359
|
+
}
|
|
336
360
|
}
|
|
337
361
|
|
|
338
362
|
// Setup DLQ exchange and bindings
|