@onlineapps/conn-infra-mq 1.1.17 → 1.1.19
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 +57 -6
package/package.json
CHANGED
|
@@ -292,17 +292,68 @@ class QueueManager {
|
|
|
292
292
|
* @param {Object} options - Queue options
|
|
293
293
|
*/
|
|
294
294
|
async createTemporaryQueue(prefix = 'temp', options = {}) {
|
|
295
|
+
const transport = this.client._transport;
|
|
296
|
+
if (!transport || !transport.channel) {
|
|
297
|
+
throw new Error('MQ client not connected');
|
|
298
|
+
}
|
|
299
|
+
// Use queueChannel for queue operations
|
|
300
|
+
const channel = transport.queueChannel || transport.channel;
|
|
301
|
+
|
|
295
302
|
const queueName = `${prefix}.${Date.now()}.${Math.random().toString(36).substr(2, 9)}`;
|
|
296
303
|
|
|
297
|
-
|
|
304
|
+
// For temporary queues (rpc.reply.*), we MUST create them explicitly
|
|
305
|
+
// because they are used immediately for consuming replies
|
|
306
|
+
// Use assertQueue directly on queueChannel to avoid RPC reply queue issues
|
|
307
|
+
const queueOptions = {
|
|
298
308
|
durable: false,
|
|
309
|
+
exclusive: options.exclusive !== false, // Default to exclusive for temporary queues
|
|
299
310
|
autoDelete: true,
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
...options
|
|
303
|
-
});
|
|
311
|
+
arguments: {}
|
|
312
|
+
};
|
|
304
313
|
|
|
305
|
-
|
|
314
|
+
// Add expires if specified
|
|
315
|
+
if (options.expires) {
|
|
316
|
+
queueOptions.arguments['x-expires'] = options.expires;
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
// CRITICAL: amqplib's assertQueue() uses RPC pattern even on regular channels
|
|
320
|
+
// This causes channel closure if reply queue doesn't exist
|
|
321
|
+
// Solution: Create queue by sending an empty message to it using default exchange
|
|
322
|
+
// This avoids RPC reply queue issues with assertQueue()
|
|
323
|
+
|
|
324
|
+
// Check if channel is open
|
|
325
|
+
if (!channel || channel.closed) {
|
|
326
|
+
throw new Error('Channel is closed - cannot create temporary queue');
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
// Use publish channel (ConfirmChannel) to send empty message, which creates the queue
|
|
330
|
+
const publishChannel = transport.channel;
|
|
331
|
+
if (!publishChannel || publishChannel.closed) {
|
|
332
|
+
throw new Error('Publish channel is closed - cannot create temporary queue');
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
try {
|
|
336
|
+
// Send empty message to create queue (RabbitMQ creates queue automatically on first sendToQueue)
|
|
337
|
+
// This avoids RPC reply queue issues with assertQueue()
|
|
338
|
+
publishChannel.sendToQueue(queueName, Buffer.from(''), {
|
|
339
|
+
persistent: false
|
|
340
|
+
});
|
|
341
|
+
|
|
342
|
+
// Wait a moment for queue to be created
|
|
343
|
+
await new Promise(resolve => setTimeout(resolve, 100));
|
|
344
|
+
|
|
345
|
+
// Verify queue exists
|
|
346
|
+
await channel.checkQueue(queueName);
|
|
347
|
+
|
|
348
|
+
this.managedQueues.add(queueName);
|
|
349
|
+
return queueName;
|
|
350
|
+
} catch (err) {
|
|
351
|
+
// If channel closed, throw descriptive error
|
|
352
|
+
if (!channel || channel.closed || !publishChannel || publishChannel.closed) {
|
|
353
|
+
throw new Error(`Channel closed during temporary queue creation for ${queueName} - RPC reply queue issue detected`);
|
|
354
|
+
}
|
|
355
|
+
throw err;
|
|
356
|
+
}
|
|
306
357
|
}
|
|
307
358
|
|
|
308
359
|
/**
|