@onlineapps/mq-client-core 1.0.26 → 1.0.28
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
|
@@ -164,8 +164,9 @@ class RabbitMQClient extends EventEmitter {
|
|
|
164
164
|
* @throws {Error} If publish fails or channel is not available.
|
|
165
165
|
*/
|
|
166
166
|
async publish(queue, buffer, options = {}) {
|
|
167
|
-
|
|
168
|
-
|
|
167
|
+
// Check channel state before publish
|
|
168
|
+
if (!this._channel || this._channel.closed) {
|
|
169
|
+
throw new Error('Cannot publish: channel is not initialized or closed');
|
|
169
170
|
}
|
|
170
171
|
|
|
171
172
|
const exchange = this._config.exchange || '';
|
|
@@ -181,15 +182,42 @@ class RabbitMQClient extends EventEmitter {
|
|
|
181
182
|
// If queue doesn't exist (404), we should NOT auto-create it - infrastructure queues must be created explicitly
|
|
182
183
|
// This prevents creating queues with wrong arguments (no TTL) which causes 406 errors later
|
|
183
184
|
try {
|
|
185
|
+
// Check queueChannel state
|
|
186
|
+
if (!this._queueChannel || this._queueChannel.closed) {
|
|
187
|
+
// Recreate queueChannel if closed
|
|
188
|
+
if (this._connection && !this._connection.closed) {
|
|
189
|
+
this._queueChannel = await this._connection.createChannel();
|
|
190
|
+
this._queueChannel.on('error', (err) => {
|
|
191
|
+
console.warn('[RabbitMQClient] Queue channel error:', err.message);
|
|
192
|
+
});
|
|
193
|
+
this._queueChannel.on('close', () => {
|
|
194
|
+
console.warn('[RabbitMQClient] Queue channel closed');
|
|
195
|
+
});
|
|
196
|
+
} else {
|
|
197
|
+
throw new Error('Cannot publish: connection is closed');
|
|
198
|
+
}
|
|
199
|
+
}
|
|
184
200
|
await this._queueChannel.checkQueue(queue);
|
|
185
201
|
// Queue exists - proceed to publish
|
|
186
202
|
} catch (checkErr) {
|
|
187
203
|
// If queue doesn't exist (404), this is an ERROR for infrastructure queues
|
|
188
|
-
// Infrastructure queues (workflow.*, registry.*) must be created explicitly with correct arguments
|
|
204
|
+
// Infrastructure queues (workflow.*, registry.*, infrastructure.*, monitoring.*, validation.*) must be created explicitly with correct arguments
|
|
189
205
|
// We should NOT auto-create them here, as we don't have access to queueConfig in mq-client-core
|
|
190
206
|
if (checkErr.code === 404) {
|
|
191
|
-
// Check if this is an infrastructure queue
|
|
192
|
-
|
|
207
|
+
// Check if this is an infrastructure queue using queueConfig
|
|
208
|
+
let isInfraQueue = false;
|
|
209
|
+
try {
|
|
210
|
+
const queueConfig = require('../config/queueConfig');
|
|
211
|
+
isInfraQueue = queueConfig.isInfrastructureQueue(queue);
|
|
212
|
+
} catch (requireErr) {
|
|
213
|
+
// Fallback to pattern matching if queueConfig not available
|
|
214
|
+
isInfraQueue = queue.startsWith('workflow.') ||
|
|
215
|
+
queue.startsWith('registry.') ||
|
|
216
|
+
queue.startsWith('infrastructure.') ||
|
|
217
|
+
queue.startsWith('monitoring.') ||
|
|
218
|
+
queue.startsWith('validation.');
|
|
219
|
+
}
|
|
220
|
+
|
|
193
221
|
if (isInfraQueue) {
|
|
194
222
|
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.`);
|
|
195
223
|
}
|
|
@@ -203,15 +231,31 @@ class RabbitMQClient extends EventEmitter {
|
|
|
203
231
|
}
|
|
204
232
|
}
|
|
205
233
|
// Publish to queue using ConfirmChannel (for publisher confirms)
|
|
234
|
+
// Check channel state again before sendToQueue
|
|
235
|
+
if (this._channel.closed) {
|
|
236
|
+
throw new Error('Cannot publish: channel closed during operation');
|
|
237
|
+
}
|
|
206
238
|
this._channel.sendToQueue(queue, buffer, { persistent, headers });
|
|
207
239
|
} else {
|
|
208
240
|
// If exchange is specified, assert exchange and publish to it
|
|
241
|
+
if (this._channel.closed) {
|
|
242
|
+
throw new Error('Cannot publish: channel closed during operation');
|
|
243
|
+
}
|
|
209
244
|
await this._channel.assertExchange(exchange, 'direct', { durable: this._config.durable });
|
|
210
245
|
this._channel.publish(exchange, routingKey, buffer, { persistent, headers });
|
|
211
246
|
}
|
|
212
|
-
// Wait for confirmation
|
|
213
|
-
|
|
247
|
+
// Wait for confirmation (with timeout to prevent hanging)
|
|
248
|
+
const confirmPromise = this._channel.waitForConfirms();
|
|
249
|
+
const timeoutPromise = new Promise((_, reject) => {
|
|
250
|
+
setTimeout(() => reject(new Error('Publisher confirm timeout after 5 seconds')), 5000);
|
|
251
|
+
});
|
|
252
|
+
await Promise.race([confirmPromise, timeoutPromise]);
|
|
214
253
|
} catch (err) {
|
|
254
|
+
// If channel was closed, mark it for recreation
|
|
255
|
+
if (err.message && (err.message.includes('Channel closed') || err.message.includes('channel is closed') || this._channel?.closed)) {
|
|
256
|
+
console.warn('[RabbitMQClient] [mq-client-core] [PUBLISH] Channel closed during publish, will need to reconnect');
|
|
257
|
+
this._channel = null;
|
|
258
|
+
}
|
|
215
259
|
this.emit('error', err);
|
|
216
260
|
throw err;
|
|
217
261
|
}
|
|
@@ -249,8 +293,10 @@ class RabbitMQClient extends EventEmitter {
|
|
|
249
293
|
console.warn(`[RabbitMQClient] [mq-client-core] [CONSUMER] Cannot load queueConfig from @onlineapps/conn-infra-mq:`, requireErr.message);
|
|
250
294
|
console.warn(`[RabbitMQClient] [mq-client-core] [CONSUMER] Using default queue options (this may cause 406 errors if queue exists with different args)`);
|
|
251
295
|
}
|
|
252
|
-
|
|
253
|
-
|
|
296
|
+
|
|
297
|
+
// Only check queue types if queueConfig is available
|
|
298
|
+
const isInfraQueue = queueConfig ? queueConfig.isInfrastructureQueue(queue) : false;
|
|
299
|
+
const isBusinessQueue = queueConfig ? queueConfig.isBusinessQueue(queue) : false;
|
|
254
300
|
|
|
255
301
|
let queueOptions = options.queueOptions || { durable };
|
|
256
302
|
|