@onlineapps/infrastructure-tools 1.0.28 → 1.0.30
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/infrastructure-tools",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.30",
|
|
4
4
|
"description": "Infrastructure orchestration utilities for OA Drive infrastructure services (health tracking, queue initialization, service discovery)",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -108,98 +108,11 @@ async function initInfrastructureQueues(channel, options = {}) {
|
|
|
108
108
|
throw configError;
|
|
109
109
|
}
|
|
110
110
|
|
|
111
|
-
// CRITICAL:
|
|
112
|
-
//
|
|
113
|
-
//
|
|
114
|
-
//
|
|
115
|
-
|
|
116
|
-
let queueNeedsRecreation = false;
|
|
117
|
-
let checkChannelForDelete = null;
|
|
118
|
-
|
|
119
|
-
try {
|
|
120
|
-
// Use a separate channel for checking queue (to avoid closing workingChannel)
|
|
121
|
-
// CRITICAL: checkQueue() does NOT create queue - it only checks existence
|
|
122
|
-
checkChannelForDelete = await connection.createChannel();
|
|
123
|
-
const queueInfo = await checkChannelForDelete.checkQueue(queueName);
|
|
124
|
-
queueExists = true;
|
|
125
|
-
|
|
126
|
-
// Check if queue has correct arguments
|
|
127
|
-
const currentArgs = queueInfo.arguments || {};
|
|
128
|
-
const expectedArgs = config.arguments || {};
|
|
129
|
-
|
|
130
|
-
// Compare arguments (TTL, max-length, etc.)
|
|
131
|
-
const argsMatch = Object.keys(expectedArgs).every(key => {
|
|
132
|
-
return currentArgs[key] === expectedArgs[key];
|
|
133
|
-
}) && Object.keys(currentArgs).every(key => {
|
|
134
|
-
// Allow extra args in current queue, but required args must match
|
|
135
|
-
return expectedArgs[key] === undefined || currentArgs[key] === expectedArgs[key];
|
|
136
|
-
});
|
|
137
|
-
|
|
138
|
-
if (!argsMatch) {
|
|
139
|
-
logger.warn(`[QueueInit] ⚠ Queue ${queueName} exists with different arguments - will delete and recreate`, {
|
|
140
|
-
current: currentArgs,
|
|
141
|
-
expected: expectedArgs
|
|
142
|
-
});
|
|
143
|
-
queueNeedsRecreation = true;
|
|
144
|
-
} else {
|
|
145
|
-
logger.log(`[QueueInit] ✓ Queue ${queueName} exists with correct parameters`);
|
|
146
|
-
// Close check channel if queue is OK
|
|
147
|
-
try {
|
|
148
|
-
await checkChannelForDelete.close();
|
|
149
|
-
checkChannelForDelete = null;
|
|
150
|
-
} catch (closeErr) {
|
|
151
|
-
// Ignore
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
} catch (checkError) {
|
|
155
|
-
// Queue doesn't exist - will be created
|
|
156
|
-
queueExists = false;
|
|
157
|
-
logger.log(`[QueueInit] Queue ${queueName} does not exist (${checkError.code || checkError.message}) - will be created`);
|
|
158
|
-
// Close check channel if queue doesn't exist
|
|
159
|
-
if (checkChannelForDelete) {
|
|
160
|
-
try {
|
|
161
|
-
await checkChannelForDelete.close();
|
|
162
|
-
checkChannelForDelete = null;
|
|
163
|
-
} catch (closeErr) {
|
|
164
|
-
// Ignore
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
// CRITICAL: If queue exists with wrong parameters, delete it first
|
|
170
|
-
// This must be done BEFORE assertQueue to avoid 406 errors
|
|
171
|
-
if (queueNeedsRecreation) {
|
|
172
|
-
try {
|
|
173
|
-
// Use the check channel for deletion (or create new one if check failed)
|
|
174
|
-
const deleteChannel = checkChannelForDelete || await connection.createChannel();
|
|
175
|
-
await deleteChannel.deleteQueue(queueName, { ifEmpty: false });
|
|
176
|
-
logger.log(`[QueueInit] ✓ Deleted queue ${queueName} with incorrect parameters`);
|
|
177
|
-
// Close delete channel after use
|
|
178
|
-
try {
|
|
179
|
-
await deleteChannel.close();
|
|
180
|
-
} catch (closeErr) {
|
|
181
|
-
// Ignore close errors
|
|
182
|
-
}
|
|
183
|
-
checkChannelForDelete = null;
|
|
184
|
-
|
|
185
|
-
// Wait to ensure deletion is processed and no frames are pending
|
|
186
|
-
await new Promise(resolve => setTimeout(resolve, 300));
|
|
187
|
-
queueExists = false; // Queue no longer exists, will be created
|
|
188
|
-
} catch (deleteError) {
|
|
189
|
-
logger.error(`[QueueInit] ✗ Failed to delete queue ${queueName}:`, deleteError.message);
|
|
190
|
-
// Clean up check channel if still open
|
|
191
|
-
if (checkChannelForDelete) {
|
|
192
|
-
try {
|
|
193
|
-
await checkChannelForDelete.close();
|
|
194
|
-
} catch (closeErr) {
|
|
195
|
-
// Ignore
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
throw new Error(`Cannot delete queue ${queueName} with incorrect parameters: ${deleteError.message}`);
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
// CRITICAL: Now create/verify queue with correct parameters
|
|
111
|
+
// CRITICAL: Create/verify queue directly with assertQueue
|
|
112
|
+
// NOTE: We do NOT use checkQueue first because:
|
|
113
|
+
// - checkQueue throws 404 if queue doesn't exist, which closes the channel
|
|
114
|
+
// - assertQueue creates queue if it doesn't exist, OR verifies params if it does
|
|
115
|
+
// - If params mismatch, we get 406 PRECONDITION-FAILED which we handle below
|
|
203
116
|
const ensureQueue = async () => {
|
|
204
117
|
const activeChannel = await getChannel();
|
|
205
118
|
return activeChannel.assertQueue(queueName, {
|
|
@@ -213,13 +126,15 @@ async function initInfrastructureQueues(channel, options = {}) {
|
|
|
213
126
|
await ensureQueue();
|
|
214
127
|
logger.log(`[QueueInit] ✓ Created/verified infrastructure queue: ${queueName}`);
|
|
215
128
|
} catch (assertError) {
|
|
216
|
-
logger.error(`[QueueInit] ✗
|
|
129
|
+
logger.error(`[QueueInit] ✗ assertQueue failed for ${queueName}:`, {
|
|
217
130
|
error: assertError.message,
|
|
218
131
|
code: assertError.code,
|
|
219
132
|
classId: assertError.classId,
|
|
220
133
|
methodId: assertError.methodId
|
|
221
134
|
});
|
|
135
|
+
|
|
222
136
|
if (assertError.code === 406) {
|
|
137
|
+
// 406 PRECONDITION-FAILED: queue exists with different parameters
|
|
223
138
|
if (alertOnMismatch) {
|
|
224
139
|
try {
|
|
225
140
|
await sendQueueMismatchAlert({
|
|
@@ -234,12 +149,11 @@ async function initInfrastructureQueues(channel, options = {}) {
|
|
|
234
149
|
logger.warn('[QueueInit] Failed to send queue mismatch alert', alertError.message);
|
|
235
150
|
}
|
|
236
151
|
}
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
152
|
+
|
|
153
|
+
logger.warn(`[QueueInit] ⚠ Queue ${queueName} exists with different arguments - deleting and recreating...`);
|
|
154
|
+
|
|
240
155
|
try {
|
|
241
|
-
//
|
|
242
|
-
// Close the current channel first to prevent it from receiving frames during deletion
|
|
156
|
+
// Close the current channel first (it's likely closed from 406 error anyway)
|
|
243
157
|
if (workingChannel && !workingChannel.__queueInitClosed) {
|
|
244
158
|
try {
|
|
245
159
|
await workingChannel.close();
|
|
@@ -249,27 +163,23 @@ async function initInfrastructureQueues(channel, options = {}) {
|
|
|
249
163
|
}
|
|
250
164
|
}
|
|
251
165
|
|
|
166
|
+
// Delete queue with fresh channel
|
|
252
167
|
const deleteChannel = await getChannel(true);
|
|
253
168
|
await deleteChannel.deleteQueue(queueName, { ifEmpty: false });
|
|
254
169
|
logger.log(`[QueueInit] ✓ Deleted queue ${queueName} with incorrect parameters`);
|
|
255
|
-
|
|
170
|
+
|
|
171
|
+
// Close delete channel
|
|
256
172
|
try {
|
|
257
173
|
await deleteChannel.close();
|
|
258
174
|
} catch (closeErr) {
|
|
259
|
-
// Ignore close errors
|
|
175
|
+
// Ignore close errors
|
|
260
176
|
}
|
|
261
177
|
} catch (deleteError) {
|
|
262
|
-
logger.error(
|
|
263
|
-
|
|
264
|
-
deleteError.message
|
|
265
|
-
);
|
|
266
|
-
throw new Error(
|
|
267
|
-
`Cannot delete queue ${queueName} with incorrect parameters: ${deleteError.message}`
|
|
268
|
-
);
|
|
178
|
+
logger.error(`[QueueInit] ✗ Failed to delete queue ${queueName}:`, deleteError.message);
|
|
179
|
+
throw new Error(`Cannot delete queue ${queueName} with incorrect parameters: ${deleteError.message}`);
|
|
269
180
|
}
|
|
270
181
|
|
|
271
|
-
//
|
|
272
|
-
// Wait a brief moment to ensure queue deletion is fully processed and no frames are pending
|
|
182
|
+
// Recreate with correct parameters using a fresh channel
|
|
273
183
|
await new Promise(resolve => setTimeout(resolve, 200));
|
|
274
184
|
const recreateChannel = await getChannel(true);
|
|
275
185
|
try {
|
|
@@ -277,17 +187,14 @@ async function initInfrastructureQueues(channel, options = {}) {
|
|
|
277
187
|
durable: config.durable !== false,
|
|
278
188
|
arguments: { ...config.arguments }
|
|
279
189
|
});
|
|
280
|
-
logger.log(
|
|
281
|
-
`[QueueInit] ✓ Recreated infrastructure queue: ${queueName} with correct parameters`
|
|
282
|
-
);
|
|
283
|
-
// Update workingChannel to the new channel for subsequent operations
|
|
190
|
+
logger.log(`[QueueInit] ✓ Recreated infrastructure queue: ${queueName} with correct parameters`);
|
|
284
191
|
workingChannel = recreateChannel;
|
|
285
192
|
} catch (recreateError) {
|
|
286
193
|
logger.error(`[QueueInit] ✗ Failed to recreate ${queueName}:`, recreateError.message);
|
|
287
194
|
throw recreateError;
|
|
288
195
|
}
|
|
289
196
|
} else {
|
|
290
|
-
|
|
197
|
+
// Other error - rethrow
|
|
291
198
|
throw assertError;
|
|
292
199
|
}
|
|
293
200
|
}
|
|
@@ -303,4 +210,3 @@ async function initInfrastructureQueues(channel, options = {}) {
|
|
|
303
210
|
module.exports = {
|
|
304
211
|
initInfrastructureQueues
|
|
305
212
|
};
|
|
306
|
-
|