@resolveio/server-lib 22.2.19 → 22.2.20
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/managers/error-auto-fix.manager.d.ts +5 -0
- package/managers/error-auto-fix.manager.js +145 -70
- package/managers/error-auto-fix.manager.js.map +1 -1
- package/managers/slow-query-verifier.manager.d.ts +8 -0
- package/managers/slow-query-verifier.manager.js +311 -194
- package/managers/slow-query-verifier.manager.js.map +1 -1
- package/managers/subscription.manager.js +3 -0
- package/managers/subscription.manager.js.map +1 -1
- package/managers/worker-dispatcher.manager.js +60 -6
- package/managers/worker-dispatcher.manager.js.map +1 -1
- package/methods/app-settings.js +2 -2
- package/methods/app-settings.js.map +1 -1
- package/package.json +1 -1
- package/server-app.js +22 -36
- package/server-app.js.map +1 -1
|
@@ -113,6 +113,7 @@ var resolveio_server_app_1 = require("../resolveio-server-app");
|
|
|
113
113
|
var common_1 = require("../util/common");
|
|
114
114
|
var mongodb_1 = require("mongodb");
|
|
115
115
|
var user_collection_1 = require("../collections/user.collection");
|
|
116
|
+
var app_setting_collection_1 = require("../collections/app-setting.collection");
|
|
116
117
|
var customer_notification_content_manager_1 = require("./customer-notification-content.manager");
|
|
117
118
|
var OPTIONAL_COLLECTION = {
|
|
118
119
|
findOne: function () { return Promise.resolve(null); },
|
|
@@ -192,12 +193,12 @@ var SlowQueryVerifier = /** @class */ (function () {
|
|
|
192
193
|
function SlowQueryVerifier(serverConfig, dependencies) {
|
|
193
194
|
var _this = this;
|
|
194
195
|
this.autoOptimizeInFlight = new Set();
|
|
196
|
+
this.appSettingsAutoOptimizeCacheExpiresAt = 0;
|
|
197
|
+
this.appSettingsAutoOptimizeCacheValue = null;
|
|
195
198
|
var resolvedDependencies = resolveSlowQueryVerifierDependencies(dependencies);
|
|
196
199
|
applySlowQueryVerifierDependencies(resolvedDependencies);
|
|
197
200
|
this.config = SlowQueryVerifier.resolveConfig(serverConfig);
|
|
198
|
-
|
|
199
|
-
this.config.autoOptimizeEnabled = false;
|
|
200
|
-
}
|
|
201
|
+
this.autoOptimizeDependenciesAvailable = !!(resolvedDependencies.AICoderApps && resolvedDependencies.AIDashboardJobs);
|
|
201
202
|
if (this.config.enabled) {
|
|
202
203
|
this._timer = setInterval(function () {
|
|
203
204
|
// eslint-disable-next-line no-restricted-syntax
|
|
@@ -214,6 +215,7 @@ var SlowQueryVerifier = /** @class */ (function () {
|
|
|
214
215
|
SlowQueryVerifier.resolveConfig = function (serverConfig) {
|
|
215
216
|
var slowQueryConfig = (serverConfig && (serverConfig.slowQuery || serverConfig.SLOW_QUERY)) || {};
|
|
216
217
|
var verifierConfig = (slowQueryConfig && (slowQueryConfig.verifier || slowQueryConfig.slowQueryVerifier)) || {};
|
|
218
|
+
var autofixConfig = (serverConfig && (serverConfig.autofix || serverConfig.AUTOFIX)) || {};
|
|
217
219
|
var getBoolean = function (envKey, configKey, fallback) {
|
|
218
220
|
if (fallback === void 0) { fallback = true; }
|
|
219
221
|
if (typeof process.env[envKey] !== 'undefined') {
|
|
@@ -239,6 +241,22 @@ var SlowQueryVerifier = /** @class */ (function () {
|
|
|
239
241
|
}
|
|
240
242
|
return fallback;
|
|
241
243
|
};
|
|
244
|
+
var getString = function (envKey, configKey, fallback) {
|
|
245
|
+
if (fallback === void 0) { fallback = ''; }
|
|
246
|
+
if (typeof process.env[envKey] !== 'undefined') {
|
|
247
|
+
return String(process.env[envKey] || '').trim();
|
|
248
|
+
}
|
|
249
|
+
if (typeof verifierConfig[configKey] !== 'undefined') {
|
|
250
|
+
return String(verifierConfig[configKey] || '').trim();
|
|
251
|
+
}
|
|
252
|
+
if (typeof slowQueryConfig[configKey] !== 'undefined') {
|
|
253
|
+
return String(slowQueryConfig[configKey] || '').trim();
|
|
254
|
+
}
|
|
255
|
+
if (typeof autofixConfig[configKey] !== 'undefined') {
|
|
256
|
+
return String(autofixConfig[configKey] || '').trim();
|
|
257
|
+
}
|
|
258
|
+
return fallback;
|
|
259
|
+
};
|
|
242
260
|
var parseEmails = function (value) {
|
|
243
261
|
if (Array.isArray(value)) {
|
|
244
262
|
return value.map(function (item) { return "".concat(item || '').trim().toLowerCase(); }).filter(Boolean);
|
|
@@ -275,10 +293,13 @@ var SlowQueryVerifier = /** @class */ (function () {
|
|
|
275
293
|
|| slowQueryConfig.escalationEmails
|
|
276
294
|
|| slowQueryConfig.notifyEmails);
|
|
277
295
|
return {
|
|
278
|
-
enabled:
|
|
296
|
+
enabled: true,
|
|
279
297
|
fallbackToMainDB: getBoolean('SLOW_QUERY_VERIFIER_FALLBACK_MAIN_DB', 'fallbackToMainDB', true),
|
|
280
298
|
debugLogging: getBoolean('SLOW_QUERY_VERIFIER_DEBUG_LOGS', 'debugLogging', false),
|
|
281
|
-
configSource:
|
|
299
|
+
configSource: Object.keys(verifierConfig).length ? 'serverConfig' : 'defaults',
|
|
300
|
+
autofixRepoRoot: getString('AUTOFIX_REPO_ROOT', 'repoRoot', '/var/app/current'),
|
|
301
|
+
autofixGithubOwner: getString('AUTOFIX_GITHUB_OWNER', 'githubOwner', 'resolveio'),
|
|
302
|
+
autofixGithubRepo: getString('AUTOFIX_GITHUB_REPO', 'githubRepo', ''),
|
|
282
303
|
autoOptimizeEnabled: getBoolean('SLOW_QUERY_AUTO_OPTIMIZE_ENABLED', 'autoOptimizeEnabled', false),
|
|
283
304
|
autoOptimizeWaitTimeoutMs: getNumber('SLOW_QUERY_AUTO_OPTIMIZE_WAIT_TIMEOUT_MS', 'autoOptimizeWaitTimeoutMs', 45 * 60 * 1000),
|
|
284
305
|
autoOptimizeDurationRatioTarget: clampRatio(getNumber('SLOW_QUERY_AUTO_OPTIMIZE_DURATION_RATIO', 'autoOptimizeDurationRatioTarget', AUTO_OPTIMIZE_DEFAULT_IMPROVEMENT_RATIO), AUTO_OPTIMIZE_DEFAULT_IMPROVEMENT_RATIO),
|
|
@@ -296,13 +317,87 @@ var SlowQueryVerifier = /** @class */ (function () {
|
|
|
296
317
|
escalationEmails: escalationEmails
|
|
297
318
|
};
|
|
298
319
|
};
|
|
320
|
+
SlowQueryVerifier.prototype.parseBooleanEnv = function (envKey) {
|
|
321
|
+
if (typeof process.env[envKey] === 'undefined') {
|
|
322
|
+
return null;
|
|
323
|
+
}
|
|
324
|
+
return process.env[envKey] === 'true';
|
|
325
|
+
};
|
|
326
|
+
SlowQueryVerifier.prototype.resolveAutoOptimizeEnabled = function () {
|
|
327
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
328
|
+
var now, envValue, enabled, activeSetting, _a, error_1;
|
|
329
|
+
var _b;
|
|
330
|
+
return __generator(this, function (_c) {
|
|
331
|
+
switch (_c.label) {
|
|
332
|
+
case 0:
|
|
333
|
+
if (!this.autoOptimizeDependenciesAvailable) {
|
|
334
|
+
return [2 /*return*/, false];
|
|
335
|
+
}
|
|
336
|
+
now = Date.now();
|
|
337
|
+
if (this.appSettingsAutoOptimizeCacheValue !== null && now < this.appSettingsAutoOptimizeCacheExpiresAt) {
|
|
338
|
+
return [2 /*return*/, this.appSettingsAutoOptimizeCacheValue];
|
|
339
|
+
}
|
|
340
|
+
envValue = this.parseBooleanEnv('SLOW_QUERY_AUTO_OPTIMIZE_ENABLED');
|
|
341
|
+
enabled = envValue !== null ? envValue : !!this.config.autoOptimizeEnabled;
|
|
342
|
+
_c.label = 1;
|
|
343
|
+
case 1:
|
|
344
|
+
_c.trys.push([1, 6, , 7]);
|
|
345
|
+
if (!(app_setting_collection_1.AppSettings && typeof app_setting_collection_1.AppSettings.findOne === 'function')) return [3 /*break*/, 5];
|
|
346
|
+
return [4 /*yield*/, app_setting_collection_1.AppSettings.findOne({
|
|
347
|
+
is_active: {
|
|
348
|
+
$ne: false
|
|
349
|
+
}
|
|
350
|
+
}, {
|
|
351
|
+
sort: {
|
|
352
|
+
updatedAt: -1,
|
|
353
|
+
createdAt: -1
|
|
354
|
+
}
|
|
355
|
+
})];
|
|
356
|
+
case 2:
|
|
357
|
+
_a = (_c.sent());
|
|
358
|
+
if (_a) return [3 /*break*/, 4];
|
|
359
|
+
return [4 /*yield*/, app_setting_collection_1.AppSettings.findOne({}, {
|
|
360
|
+
sort: {
|
|
361
|
+
updatedAt: -1,
|
|
362
|
+
createdAt: -1
|
|
363
|
+
}
|
|
364
|
+
})];
|
|
365
|
+
case 3:
|
|
366
|
+
_a = (_c.sent());
|
|
367
|
+
_c.label = 4;
|
|
368
|
+
case 4:
|
|
369
|
+
activeSetting = _a;
|
|
370
|
+
if (activeSetting && typeof activeSetting.enable_slow_query_optimizer === 'boolean') {
|
|
371
|
+
enabled = !!activeSetting.enable_slow_query_optimizer;
|
|
372
|
+
}
|
|
373
|
+
_c.label = 5;
|
|
374
|
+
case 5: return [3 /*break*/, 7];
|
|
375
|
+
case 6:
|
|
376
|
+
error_1 = _c.sent();
|
|
377
|
+
if ((_b = this.config) === null || _b === void 0 ? void 0 : _b.debugLogging) {
|
|
378
|
+
console.warn('SlowQueryVerifier failed to read app settings slow-query optimizer toggle', error_1);
|
|
379
|
+
}
|
|
380
|
+
return [3 /*break*/, 7];
|
|
381
|
+
case 7:
|
|
382
|
+
this.appSettingsAutoOptimizeCacheValue = enabled;
|
|
383
|
+
this.appSettingsAutoOptimizeCacheExpiresAt = now + SlowQueryVerifier.APP_SETTINGS_CACHE_TTL_MS;
|
|
384
|
+
return [2 /*return*/, enabled];
|
|
385
|
+
}
|
|
386
|
+
});
|
|
387
|
+
});
|
|
388
|
+
};
|
|
299
389
|
SlowQueryVerifier.prototype.poll = function () {
|
|
300
390
|
return __awaiter(this, void 0, void 0, function () {
|
|
301
|
-
var now, candidates, candidates_1, candidates_1_1, candidate, e_1_1;
|
|
391
|
+
var autoOptimizeEnabled, now, candidates, candidates_1, candidates_1_1, candidate, e_1_1;
|
|
302
392
|
var e_1, _a;
|
|
303
393
|
return __generator(this, function (_b) {
|
|
304
394
|
switch (_b.label) {
|
|
305
|
-
case 0:
|
|
395
|
+
case 0: return [4 /*yield*/, this.resolveAutoOptimizeEnabled()];
|
|
396
|
+
case 1:
|
|
397
|
+
autoOptimizeEnabled = _b.sent();
|
|
398
|
+
if (!autoOptimizeEnabled) {
|
|
399
|
+
return [2 /*return*/];
|
|
400
|
+
}
|
|
306
401
|
now = new Date();
|
|
307
402
|
return [4 /*yield*/, SlowQueryLogs.find({
|
|
308
403
|
ignored: {
|
|
@@ -330,35 +425,35 @@ var SlowQueryVerifier = /** @class */ (function () {
|
|
|
330
425
|
},
|
|
331
426
|
limit: 5
|
|
332
427
|
})];
|
|
333
|
-
case 1:
|
|
334
|
-
candidates = _b.sent();
|
|
335
|
-
_b.label = 2;
|
|
336
428
|
case 2:
|
|
337
|
-
_b.
|
|
338
|
-
candidates_1 = __values(candidates), candidates_1_1 = candidates_1.next();
|
|
429
|
+
candidates = _b.sent();
|
|
339
430
|
_b.label = 3;
|
|
340
431
|
case 3:
|
|
341
|
-
|
|
432
|
+
_b.trys.push([3, 8, 9, 10]);
|
|
433
|
+
candidates_1 = __values(candidates), candidates_1_1 = candidates_1.next();
|
|
434
|
+
_b.label = 4;
|
|
435
|
+
case 4:
|
|
436
|
+
if (!!candidates_1_1.done) return [3 /*break*/, 7];
|
|
342
437
|
candidate = candidates_1_1.value;
|
|
343
438
|
return [4 /*yield*/, this.processCandidate(candidate)];
|
|
344
|
-
case 4:
|
|
345
|
-
_b.sent();
|
|
346
|
-
_b.label = 5;
|
|
347
439
|
case 5:
|
|
440
|
+
_b.sent();
|
|
441
|
+
_b.label = 6;
|
|
442
|
+
case 6:
|
|
348
443
|
candidates_1_1 = candidates_1.next();
|
|
349
|
-
return [3 /*break*/,
|
|
350
|
-
case
|
|
351
|
-
case
|
|
444
|
+
return [3 /*break*/, 4];
|
|
445
|
+
case 7: return [3 /*break*/, 10];
|
|
446
|
+
case 8:
|
|
352
447
|
e_1_1 = _b.sent();
|
|
353
448
|
e_1 = { error: e_1_1 };
|
|
354
|
-
return [3 /*break*/,
|
|
355
|
-
case
|
|
449
|
+
return [3 /*break*/, 10];
|
|
450
|
+
case 9:
|
|
356
451
|
try {
|
|
357
452
|
if (candidates_1_1 && !candidates_1_1.done && (_a = candidates_1.return)) _a.call(candidates_1);
|
|
358
453
|
}
|
|
359
454
|
finally { if (e_1) throw e_1.error; }
|
|
360
455
|
return [7 /*endfinally*/];
|
|
361
|
-
case
|
|
456
|
+
case 10: return [2 /*return*/];
|
|
362
457
|
}
|
|
363
458
|
});
|
|
364
459
|
});
|
|
@@ -564,7 +659,7 @@ var SlowQueryVerifier = /** @class */ (function () {
|
|
|
564
659
|
queuedLog = (_a.sent()) || existing;
|
|
565
660
|
this.autoOptimizeInFlight.add(logId);
|
|
566
661
|
setImmediate(function () { return __awaiter(_this, void 0, void 0, function () {
|
|
567
|
-
var
|
|
662
|
+
var error_2;
|
|
568
663
|
return __generator(this, function (_a) {
|
|
569
664
|
switch (_a.label) {
|
|
570
665
|
case 0:
|
|
@@ -577,8 +672,8 @@ var SlowQueryVerifier = /** @class */ (function () {
|
|
|
577
672
|
_a.sent();
|
|
578
673
|
return [3 /*break*/, 4];
|
|
579
674
|
case 2:
|
|
580
|
-
|
|
581
|
-
console.error('Slow query queued run failed', { logId: logId, error: (
|
|
675
|
+
error_2 = _a.sent();
|
|
676
|
+
console.error('Slow query queued run failed', { logId: logId, error: (error_2 === null || error_2 === void 0 ? void 0 : error_2.message) || error_2 });
|
|
582
677
|
return [3 /*break*/, 4];
|
|
583
678
|
case 3:
|
|
584
679
|
this.autoOptimizeInFlight.delete(logId);
|
|
@@ -598,7 +693,7 @@ var SlowQueryVerifier = /** @class */ (function () {
|
|
|
598
693
|
};
|
|
599
694
|
SlowQueryVerifier.prototype.deployLog = function (logId) {
|
|
600
695
|
return __awaiter(this, void 0, void 0, function () {
|
|
601
|
-
var log, jobId, job, publishOutcome, now, existingResult, refreshed,
|
|
696
|
+
var log, jobId, job, publishOutcome, now, existingResult, refreshed, error_3, message, refreshed;
|
|
602
697
|
return __generator(this, function (_a) {
|
|
603
698
|
switch (_a.label) {
|
|
604
699
|
case 0:
|
|
@@ -659,8 +754,8 @@ var SlowQueryVerifier = /** @class */ (function () {
|
|
|
659
754
|
log: refreshed
|
|
660
755
|
}];
|
|
661
756
|
case 6:
|
|
662
|
-
|
|
663
|
-
message = (
|
|
757
|
+
error_3 = _a.sent();
|
|
758
|
+
message = (error_3 === null || error_3 === void 0 ? void 0 : error_3.message) || 'Manual deploy failed.';
|
|
664
759
|
return [4 /*yield*/, SlowQueryLogs.updateOne({ _id: logId }, {
|
|
665
760
|
$set: {
|
|
666
761
|
verification_notes: "Manual deploy failed: ".concat(message),
|
|
@@ -1128,7 +1223,7 @@ var SlowQueryVerifier = /** @class */ (function () {
|
|
|
1128
1223
|
});
|
|
1129
1224
|
};
|
|
1130
1225
|
SlowQueryVerifier.prototype.scheduleAutoOptimization = function (logId) {
|
|
1131
|
-
if (!
|
|
1226
|
+
if (!logId) {
|
|
1132
1227
|
return;
|
|
1133
1228
|
}
|
|
1134
1229
|
if (this.autoOptimizeInFlight.has(logId)) {
|
|
@@ -1140,7 +1235,7 @@ var SlowQueryVerifier = /** @class */ (function () {
|
|
|
1140
1235
|
SlowQueryVerifier.prototype.runAutoOptimizationInBackground = function (logId) {
|
|
1141
1236
|
var _this = this;
|
|
1142
1237
|
setImmediate(function () { return __awaiter(_this, void 0, void 0, function () {
|
|
1143
|
-
var
|
|
1238
|
+
var error_4;
|
|
1144
1239
|
return __generator(this, function (_a) {
|
|
1145
1240
|
switch (_a.label) {
|
|
1146
1241
|
case 0:
|
|
@@ -1150,8 +1245,8 @@ var SlowQueryVerifier = /** @class */ (function () {
|
|
|
1150
1245
|
_a.sent();
|
|
1151
1246
|
return [3 /*break*/, 4];
|
|
1152
1247
|
case 2:
|
|
1153
|
-
|
|
1154
|
-
console.error('Slow query auto optimization failed', { logId: logId, error: (
|
|
1248
|
+
error_4 = _a.sent();
|
|
1249
|
+
console.error('Slow query auto optimization failed', { logId: logId, error: (error_4 === null || error_4 === void 0 ? void 0 : error_4.message) || error_4 });
|
|
1155
1250
|
return [3 /*break*/, 4];
|
|
1156
1251
|
case 3:
|
|
1157
1252
|
this.autoOptimizeInFlight.delete(logId);
|
|
@@ -1179,7 +1274,7 @@ var SlowQueryVerifier = /** @class */ (function () {
|
|
|
1179
1274
|
};
|
|
1180
1275
|
SlowQueryVerifier.prototype.sendSlowQueryEscalationNotice = function (log, reason) {
|
|
1181
1276
|
return __awaiter(this, void 0, void 0, function () {
|
|
1182
|
-
var recipients, subject, body, methodManager, recipients_1, recipients_1_1, recipient,
|
|
1277
|
+
var recipients, subject, body, methodManager, recipients_1, recipients_1_1, recipient, error_5, e_2_1;
|
|
1183
1278
|
var e_2, _a;
|
|
1184
1279
|
return __generator(this, function (_b) {
|
|
1185
1280
|
switch (_b.label) {
|
|
@@ -1220,8 +1315,8 @@ var SlowQueryVerifier = /** @class */ (function () {
|
|
|
1220
1315
|
_b.sent();
|
|
1221
1316
|
return [3 /*break*/, 6];
|
|
1222
1317
|
case 5:
|
|
1223
|
-
|
|
1224
|
-
console.error('Failed sending slow-query escalation email', { recipient: recipient, logId: log._id, error:
|
|
1318
|
+
error_5 = _b.sent();
|
|
1319
|
+
console.error('Failed sending slow-query escalation email', { recipient: recipient, logId: log._id, error: error_5 });
|
|
1225
1320
|
return [3 /*break*/, 6];
|
|
1226
1321
|
case 6:
|
|
1227
1322
|
recipients_1_1 = recipients_1.next();
|
|
@@ -1484,7 +1579,7 @@ var SlowQueryVerifier = /** @class */ (function () {
|
|
|
1484
1579
|
};
|
|
1485
1580
|
SlowQueryVerifier.prototype.notifyCustomerSlowQueryStatus = function (stage, log, extra) {
|
|
1486
1581
|
return __awaiter(this, void 0, void 0, function () {
|
|
1487
|
-
var target, isGeneratedApp, generatedApp, issueKey, dedupeKey, metadata, targetPayload, idUsers, payload,
|
|
1582
|
+
var target, isGeneratedApp, generatedApp, issueKey, dedupeKey, metadata, targetPayload, idUsers, payload, error_6;
|
|
1488
1583
|
return __generator(this, function (_a) {
|
|
1489
1584
|
switch (_a.label) {
|
|
1490
1585
|
case 0:
|
|
@@ -1580,12 +1675,12 @@ var SlowQueryVerifier = /** @class */ (function () {
|
|
|
1580
1675
|
_a.sent();
|
|
1581
1676
|
return [3 /*break*/, 12];
|
|
1582
1677
|
case 11:
|
|
1583
|
-
|
|
1678
|
+
error_6 = _a.sent();
|
|
1584
1679
|
if (this.config.debugLogging) {
|
|
1585
1680
|
console.warn('Slow query customer notification failed', {
|
|
1586
1681
|
logId: log._id,
|
|
1587
1682
|
stage: stage,
|
|
1588
|
-
error: (
|
|
1683
|
+
error: (error_6 === null || error_6 === void 0 ? void 0 : error_6.message) || error_6
|
|
1589
1684
|
});
|
|
1590
1685
|
}
|
|
1591
1686
|
return [3 /*break*/, 12];
|
|
@@ -1918,7 +2013,7 @@ var SlowQueryVerifier = /** @class */ (function () {
|
|
|
1918
2013
|
};
|
|
1919
2014
|
SlowQueryVerifier.prototype.createDashboardJob = function (payload) {
|
|
1920
2015
|
return __awaiter(this, void 0, void 0, function () {
|
|
1921
|
-
var methodManager,
|
|
2016
|
+
var methodManager, error_7, manager;
|
|
1922
2017
|
return __generator(this, function (_a) {
|
|
1923
2018
|
switch (_a.label) {
|
|
1924
2019
|
case 0:
|
|
@@ -1929,9 +2024,9 @@ var SlowQueryVerifier = /** @class */ (function () {
|
|
|
1929
2024
|
return [4 /*yield*/, methodManager.callMethod('aiDashboardCreateJob', payload)];
|
|
1930
2025
|
case 2: return [2 /*return*/, _a.sent()];
|
|
1931
2026
|
case 3:
|
|
1932
|
-
|
|
1933
|
-
if (!this.shouldFallbackDashboardMethod(
|
|
1934
|
-
throw
|
|
2027
|
+
error_7 = _a.sent();
|
|
2028
|
+
if (!this.shouldFallbackDashboardMethod(error_7)) {
|
|
2029
|
+
throw error_7;
|
|
1935
2030
|
}
|
|
1936
2031
|
return [3 /*break*/, 4];
|
|
1937
2032
|
case 4:
|
|
@@ -1946,7 +2041,7 @@ var SlowQueryVerifier = /** @class */ (function () {
|
|
|
1946
2041
|
};
|
|
1947
2042
|
SlowQueryVerifier.prototype.waitForDashboardJobStop = function (jobId, timeoutMs) {
|
|
1948
2043
|
return __awaiter(this, void 0, void 0, function () {
|
|
1949
|
-
var methodManager,
|
|
2044
|
+
var methodManager, error_8, manager;
|
|
1950
2045
|
return __generator(this, function (_a) {
|
|
1951
2046
|
switch (_a.label) {
|
|
1952
2047
|
case 0:
|
|
@@ -1959,9 +2054,9 @@ var SlowQueryVerifier = /** @class */ (function () {
|
|
|
1959
2054
|
_a.sent();
|
|
1960
2055
|
return [2 /*return*/];
|
|
1961
2056
|
case 3:
|
|
1962
|
-
|
|
1963
|
-
if (!this.shouldFallbackDashboardMethod(
|
|
1964
|
-
throw
|
|
2057
|
+
error_8 = _a.sent();
|
|
2058
|
+
if (!this.shouldFallbackDashboardMethod(error_8)) {
|
|
2059
|
+
throw error_8;
|
|
1965
2060
|
}
|
|
1966
2061
|
return [3 /*break*/, 4];
|
|
1967
2062
|
case 4:
|
|
@@ -1978,7 +2073,7 @@ var SlowQueryVerifier = /** @class */ (function () {
|
|
|
1978
2073
|
};
|
|
1979
2074
|
SlowQueryVerifier.prototype.isDashboardJobRunning = function (jobId) {
|
|
1980
2075
|
return __awaiter(this, void 0, void 0, function () {
|
|
1981
|
-
var methodManager, running,
|
|
2076
|
+
var methodManager, running, error_9, manager;
|
|
1982
2077
|
return __generator(this, function (_a) {
|
|
1983
2078
|
switch (_a.label) {
|
|
1984
2079
|
case 0:
|
|
@@ -1991,9 +2086,9 @@ var SlowQueryVerifier = /** @class */ (function () {
|
|
|
1991
2086
|
running = _a.sent();
|
|
1992
2087
|
return [2 /*return*/, !!running];
|
|
1993
2088
|
case 3:
|
|
1994
|
-
|
|
1995
|
-
if (!this.shouldFallbackDashboardMethod(
|
|
1996
|
-
throw
|
|
2089
|
+
error_9 = _a.sent();
|
|
2090
|
+
if (!this.shouldFallbackDashboardMethod(error_9)) {
|
|
2091
|
+
throw error_9;
|
|
1997
2092
|
}
|
|
1998
2093
|
return [3 /*break*/, 4];
|
|
1999
2094
|
case 4:
|
|
@@ -2008,7 +2103,7 @@ var SlowQueryVerifier = /** @class */ (function () {
|
|
|
2008
2103
|
};
|
|
2009
2104
|
SlowQueryVerifier.prototype.publishDashboardJob = function (jobId) {
|
|
2010
2105
|
return __awaiter(this, void 0, void 0, function () {
|
|
2011
|
-
var methodManager,
|
|
2106
|
+
var methodManager, error_10, manager;
|
|
2012
2107
|
return __generator(this, function (_a) {
|
|
2013
2108
|
switch (_a.label) {
|
|
2014
2109
|
case 0:
|
|
@@ -2019,9 +2114,9 @@ var SlowQueryVerifier = /** @class */ (function () {
|
|
|
2019
2114
|
return [4 /*yield*/, methodManager.callMethod('aiDashboardPublishJob', jobId)];
|
|
2020
2115
|
case 2: return [2 /*return*/, _a.sent()];
|
|
2021
2116
|
case 3:
|
|
2022
|
-
|
|
2023
|
-
if (!this.shouldFallbackDashboardMethod(
|
|
2024
|
-
throw
|
|
2117
|
+
error_10 = _a.sent();
|
|
2118
|
+
if (!this.shouldFallbackDashboardMethod(error_10)) {
|
|
2119
|
+
throw error_10;
|
|
2025
2120
|
}
|
|
2026
2121
|
return [3 /*break*/, 4];
|
|
2027
2122
|
case 4:
|
|
@@ -2390,7 +2485,7 @@ var SlowQueryVerifier = /** @class */ (function () {
|
|
|
2390
2485
|
}
|
|
2391
2486
|
return "".concat(index + 1, ". ").concat(stage.stage, " @ ").concat(stage.path).concat(metrics.length ? " (".concat(metrics.join(', '), ")") : '');
|
|
2392
2487
|
};
|
|
2393
|
-
SlowQueryVerifier.prototype.buildSlowQueryAutoOptimizeDescription = function (log, app, baseline) {
|
|
2488
|
+
SlowQueryVerifier.prototype.buildSlowQueryAutoOptimizeDescription = function (log, app, baseline, repoSlug) {
|
|
2394
2489
|
var _this = this;
|
|
2395
2490
|
var topStages = Array.isArray(baseline.topStages) ? baseline.topStages : [];
|
|
2396
2491
|
var lookupExprInCount = SlowQueryVerifier.countLookupExprInPattern(Array.isArray(log.pipeline) ? log.pipeline : []);
|
|
@@ -2412,7 +2507,7 @@ var SlowQueryVerifier = /** @class */ (function () {
|
|
|
2412
2507
|
'12. Publish to default branch and deploy artifacts automatically after build success.',
|
|
2413
2508
|
'',
|
|
2414
2509
|
"App: ".concat(app.name || app._id),
|
|
2415
|
-
"Repo: ".concat(app.repo || 'unknown'),
|
|
2510
|
+
"Repo: ".concat(repoSlug || app.repo || 'unknown'),
|
|
2416
2511
|
"Slow Query #: ".concat(log.slow_query_count_string || log._id || ''),
|
|
2417
2512
|
"Workspace Context Id: ".concat(String((log === null || log === void 0 ? void 0 : log._id) || '').trim() || 'n/a'),
|
|
2418
2513
|
"Workspace Path: /var/ai-workspace/".concat(String((log === null || log === void 0 ? void 0 : log._id) || '').trim() || '<id_slow_query>'),
|
|
@@ -2449,6 +2544,23 @@ var SlowQueryVerifier = /** @class */ (function () {
|
|
|
2449
2544
|
], false);
|
|
2450
2545
|
return lines.join('\n');
|
|
2451
2546
|
};
|
|
2547
|
+
SlowQueryVerifier.prototype.resolveAutoOptimizeRepoSlug = function (app) {
|
|
2548
|
+
var _a, _b;
|
|
2549
|
+
var configuredRepo = String(((_a = this.config) === null || _a === void 0 ? void 0 : _a.autofixGithubRepo) || '').trim();
|
|
2550
|
+
var configuredOwner = String(((_b = this.config) === null || _b === void 0 ? void 0 : _b.autofixGithubOwner) || 'resolveio').trim() || 'resolveio';
|
|
2551
|
+
if (configuredRepo) {
|
|
2552
|
+
return "".concat(configuredOwner, "/").concat(configuredRepo);
|
|
2553
|
+
}
|
|
2554
|
+
return String((app === null || app === void 0 ? void 0 : app.repo) || '').trim();
|
|
2555
|
+
};
|
|
2556
|
+
SlowQueryVerifier.prototype.resolveAutoOptimizeRepoPath = function (app) {
|
|
2557
|
+
var _a;
|
|
2558
|
+
var configuredPath = String(((_a = this.config) === null || _a === void 0 ? void 0 : _a.autofixRepoRoot) || '').trim();
|
|
2559
|
+
if (configuredPath) {
|
|
2560
|
+
return configuredPath;
|
|
2561
|
+
}
|
|
2562
|
+
return String((app === null || app === void 0 ? void 0 : app.git_local_path) || '').trim();
|
|
2563
|
+
};
|
|
2452
2564
|
SlowQueryVerifier.queryHasExplicitSort = function (pipeline, findOptions) {
|
|
2453
2565
|
var hasFindSort = !!((findOptions === null || findOptions === void 0 ? void 0 : findOptions.sort) && typeof findOptions.sort === 'object' && Object.keys(findOptions.sort).length);
|
|
2454
2566
|
if (hasFindSort) {
|
|
@@ -2871,16 +2983,18 @@ var SlowQueryVerifier = /** @class */ (function () {
|
|
|
2871
2983
|
};
|
|
2872
2984
|
SlowQueryVerifier.prototype.runAutoOptimization = function (logId_1) {
|
|
2873
2985
|
return __awaiter(this, arguments, void 0, function (logId, force) {
|
|
2874
|
-
var log, attemptsUsed, maxAttempts, cooldownDeadline, fingerprintMaxAttempts, windowHours, windowStart, fingerprintAttempts, app, tokenEligibility, reason, baselineExplain,
|
|
2986
|
+
var autoOptimizeEnabled, log, attemptsUsed, maxAttempts, cooldownDeadline, fingerprintMaxAttempts, windowHours, windowStart, fingerprintAttempts, app, resolvedRepoSlug, resolvedRepoPath, tokenEligibility, reason, baselineExplain, error_11, baselineFallbackDuration, baselineDurationMs, baselineMetrics, baselineOutputFingerprint, error_12, title, description, job, error_13, jobId, attemptStartedAt, queuedLog, error_14, isRunning, error_15, finalJob, publishOutcome, refreshedLog, afterExplain, error_16, afterMetrics, outputEquivalence, afterOutputFingerprint, error_17, validation, autoFixResult, optimizedLog;
|
|
2875
2987
|
if (force === void 0) { force = false; }
|
|
2876
2988
|
return __generator(this, function (_a) {
|
|
2877
2989
|
switch (_a.label) {
|
|
2878
|
-
case 0:
|
|
2879
|
-
|
|
2990
|
+
case 0: return [4 /*yield*/, this.resolveAutoOptimizeEnabled()];
|
|
2991
|
+
case 1:
|
|
2992
|
+
autoOptimizeEnabled = _a.sent();
|
|
2993
|
+
if (!logId || (!autoOptimizeEnabled && !force)) {
|
|
2880
2994
|
return [2 /*return*/];
|
|
2881
2995
|
}
|
|
2882
2996
|
return [4 /*yield*/, SlowQueryLogs.findOne({ _id: logId })];
|
|
2883
|
-
case
|
|
2997
|
+
case 2:
|
|
2884
2998
|
log = _a.sent();
|
|
2885
2999
|
if (!log || !log._id || log.ignored) {
|
|
2886
3000
|
return [2 /*return*/];
|
|
@@ -2894,164 +3008,166 @@ var SlowQueryVerifier = /** @class */ (function () {
|
|
|
2894
3008
|
if (log.auto_fix_status === 'queued' && String(log.openai_task_id || '').trim()) {
|
|
2895
3009
|
return [2 /*return*/];
|
|
2896
3010
|
}
|
|
2897
|
-
if (!!force) return [3 /*break*/,
|
|
3011
|
+
if (!!force) return [3 /*break*/, 9];
|
|
2898
3012
|
attemptsUsed = Number.isFinite(Number(log.auto_fix_attempt_count))
|
|
2899
3013
|
? Number(log.auto_fix_attempt_count)
|
|
2900
3014
|
: 0;
|
|
2901
3015
|
maxAttempts = Number.isFinite(Number(this.config.autoOptimizeMaxAttemptsPerQuery))
|
|
2902
3016
|
? Number(this.config.autoOptimizeMaxAttemptsPerQuery)
|
|
2903
3017
|
: 0;
|
|
2904
|
-
if (!(maxAttempts > 0 && attemptsUsed >= maxAttempts)) return [3 /*break*/,
|
|
3018
|
+
if (!(maxAttempts > 0 && attemptsUsed >= maxAttempts)) return [3 /*break*/, 4];
|
|
2905
3019
|
return [4 /*yield*/, this.markAutoOptimizeBudgetExceeded(log, 'Auto optimize skipped')];
|
|
2906
|
-
case
|
|
3020
|
+
case 3:
|
|
2907
3021
|
_a.sent();
|
|
2908
3022
|
return [2 /*return*/];
|
|
2909
|
-
case
|
|
3023
|
+
case 4:
|
|
2910
3024
|
cooldownDeadline = this.resolveCooldownDeadline(log);
|
|
2911
|
-
if (!(cooldownDeadline && cooldownDeadline.getTime() > Date.now())) return [3 /*break*/,
|
|
3025
|
+
if (!(cooldownDeadline && cooldownDeadline.getTime() > Date.now())) return [3 /*break*/, 6];
|
|
2912
3026
|
return [4 /*yield*/, this.markAutoOptimizeCooldownActive(log, cooldownDeadline)];
|
|
2913
|
-
case
|
|
3027
|
+
case 5:
|
|
2914
3028
|
_a.sent();
|
|
2915
3029
|
return [2 /*return*/];
|
|
2916
|
-
case
|
|
3030
|
+
case 6:
|
|
2917
3031
|
fingerprintMaxAttempts = Number.isFinite(Number(this.config.autoOptimizeMaxAttemptsPerFingerprint))
|
|
2918
3032
|
? Number(this.config.autoOptimizeMaxAttemptsPerFingerprint)
|
|
2919
3033
|
: 0;
|
|
2920
|
-
if (!(fingerprintMaxAttempts > 0)) return [3 /*break*/,
|
|
3034
|
+
if (!(fingerprintMaxAttempts > 0)) return [3 /*break*/, 9];
|
|
2921
3035
|
windowHours = Number.isFinite(Number(this.config.autoOptimizeFingerprintWindowHours))
|
|
2922
3036
|
? Number(this.config.autoOptimizeFingerprintWindowHours)
|
|
2923
3037
|
: AUTO_OPTIMIZE_DEFAULT_FINGERPRINT_WINDOW_HOURS;
|
|
2924
3038
|
windowStart = new Date(Date.now() - (windowHours * 60 * 60 * 1000));
|
|
2925
3039
|
return [4 /*yield*/, this.resolveFingerprintAttemptsInWindow(log, windowStart)];
|
|
2926
|
-
case
|
|
3040
|
+
case 7:
|
|
2927
3041
|
fingerprintAttempts = _a.sent();
|
|
2928
|
-
if (!(fingerprintAttempts >= fingerprintMaxAttempts)) return [3 /*break*/,
|
|
3042
|
+
if (!(fingerprintAttempts >= fingerprintMaxAttempts)) return [3 /*break*/, 9];
|
|
2929
3043
|
return [4 /*yield*/, this.markAutoOptimizeBudgetExceeded(log, "Auto optimize skipped: fingerprint budget reached (".concat(fingerprintAttempts, "/").concat(fingerprintMaxAttempts, ") in the last ").concat(windowHours, "h."))];
|
|
2930
|
-
case
|
|
3044
|
+
case 8:
|
|
2931
3045
|
_a.sent();
|
|
2932
3046
|
return [2 /*return*/];
|
|
2933
|
-
case
|
|
2934
|
-
case
|
|
3047
|
+
case 9: return [4 /*yield*/, this.resolveAutoOptimizeApp(log)];
|
|
3048
|
+
case 10:
|
|
2935
3049
|
app = _a.sent();
|
|
2936
|
-
|
|
3050
|
+
resolvedRepoSlug = this.resolveAutoOptimizeRepoSlug(app);
|
|
3051
|
+
resolvedRepoPath = this.resolveAutoOptimizeRepoPath(app);
|
|
3052
|
+
if (!(!(app === null || app === void 0 ? void 0 : app._id) || !resolvedRepoSlug)) return [3 /*break*/, 12];
|
|
2937
3053
|
return [4 /*yield*/, SlowQueryLogs.updateOne({ _id: logId }, {
|
|
2938
3054
|
$set: {
|
|
2939
3055
|
status: 'investigating',
|
|
2940
3056
|
auto_fix_status: 'failed',
|
|
2941
|
-
verification_notes: 'Auto optimize skipped: unable to map slow query to AI Coder app/repo.',
|
|
3057
|
+
verification_notes: 'Auto optimize skipped: unable to map slow query to AI Coder app/repo configuration.',
|
|
2942
3058
|
last_triaged_by: 'auto-slow-query',
|
|
2943
3059
|
last_triaged_at: new Date()
|
|
2944
3060
|
}
|
|
2945
3061
|
})];
|
|
2946
|
-
case
|
|
3062
|
+
case 11:
|
|
2947
3063
|
_a.sent();
|
|
2948
3064
|
return [2 /*return*/];
|
|
2949
|
-
case
|
|
2950
|
-
case
|
|
3065
|
+
case 12: return [4 /*yield*/, checkAICoderTokenEligibility(app._id, this.config.autoOptimizeRequiredTokens > 0 ? this.config.autoOptimizeRequiredTokens : undefined)];
|
|
3066
|
+
case 13:
|
|
2951
3067
|
tokenEligibility = _a.sent();
|
|
2952
|
-
if (!!tokenEligibility.allowed) return [3 /*break*/,
|
|
3068
|
+
if (!!tokenEligibility.allowed) return [3 /*break*/, 15];
|
|
2953
3069
|
reason = "".concat(tokenEligibility.message, " Available: ").concat(tokenEligibility.summary.available_tokens.toLocaleString(), " tokens; required: ").concat(tokenEligibility.required_tokens.toLocaleString(), ".");
|
|
2954
3070
|
return [4 /*yield*/, this.markAutoOptimizeTokenIneligible(log, reason)];
|
|
2955
|
-
case
|
|
3071
|
+
case 14:
|
|
2956
3072
|
_a.sent();
|
|
2957
3073
|
return [2 /*return*/];
|
|
2958
|
-
case 14:
|
|
2959
|
-
_a.trys.push([14, 16, , 19]);
|
|
2960
|
-
return [4 /*yield*/, this.runExplain(log)];
|
|
2961
3074
|
case 15:
|
|
2962
|
-
|
|
2963
|
-
return [
|
|
3075
|
+
_a.trys.push([15, 17, , 20]);
|
|
3076
|
+
return [4 /*yield*/, this.runExplain(log)];
|
|
2964
3077
|
case 16:
|
|
2965
|
-
|
|
3078
|
+
baselineExplain = _a.sent();
|
|
3079
|
+
return [3 /*break*/, 20];
|
|
3080
|
+
case 17:
|
|
3081
|
+
error_11 = _a.sent();
|
|
2966
3082
|
return [4 /*yield*/, SlowQueryLogs.updateOne({ _id: logId }, {
|
|
2967
3083
|
$set: {
|
|
2968
3084
|
status: 'investigating',
|
|
2969
3085
|
auto_fix_status: 'failed',
|
|
2970
3086
|
auto_fix_result: {
|
|
2971
|
-
baseline_error: (
|
|
3087
|
+
baseline_error: (error_11 === null || error_11 === void 0 ? void 0 : error_11.message) || 'unknown'
|
|
2972
3088
|
},
|
|
2973
|
-
verification_notes: "Auto optimize baseline measurement failed: ".concat((
|
|
3089
|
+
verification_notes: "Auto optimize baseline measurement failed: ".concat((error_11 === null || error_11 === void 0 ? void 0 : error_11.message) || 'unknown error'),
|
|
2974
3090
|
last_triaged_by: 'auto-slow-query',
|
|
2975
3091
|
last_triaged_at: new Date()
|
|
2976
3092
|
}
|
|
2977
3093
|
})];
|
|
2978
|
-
case
|
|
3094
|
+
case 18:
|
|
2979
3095
|
_a.sent();
|
|
2980
3096
|
return [4 /*yield*/, this.maybeStopAutoOptimizeAfterFailure(logId, 'Auto optimize baseline measurement failed')];
|
|
2981
|
-
case
|
|
3097
|
+
case 19:
|
|
2982
3098
|
_a.sent();
|
|
2983
3099
|
return [2 /*return*/];
|
|
2984
|
-
case
|
|
3100
|
+
case 20:
|
|
2985
3101
|
baselineFallbackDuration = this.resolveBaselineDurationMs(log);
|
|
2986
3102
|
baselineDurationMs = SlowQueryVerifier.isValidDuration(baselineExplain.durationMs)
|
|
2987
3103
|
? baselineExplain.durationMs
|
|
2988
3104
|
: baselineFallbackDuration;
|
|
2989
3105
|
baselineMetrics = this.resolveExecutionMetrics(baselineExplain.explainStats || {}, baselineDurationMs, baselineExplain.stageSummaries || []);
|
|
2990
|
-
if (!this.config.autoOptimizeOutputCompareEnabled) return [3 /*break*/,
|
|
2991
|
-
_a.label =
|
|
2992
|
-
case 20:
|
|
2993
|
-
_a.trys.push([20, 22, , 25]);
|
|
2994
|
-
return [4 /*yield*/, this.captureOutputFingerprint(log)];
|
|
3106
|
+
if (!this.config.autoOptimizeOutputCompareEnabled) return [3 /*break*/, 26];
|
|
3107
|
+
_a.label = 21;
|
|
2995
3108
|
case 21:
|
|
2996
|
-
|
|
2997
|
-
return [
|
|
3109
|
+
_a.trys.push([21, 23, , 26]);
|
|
3110
|
+
return [4 /*yield*/, this.captureOutputFingerprint(log)];
|
|
2998
3111
|
case 22:
|
|
2999
|
-
|
|
3112
|
+
baselineOutputFingerprint = _a.sent();
|
|
3113
|
+
return [3 /*break*/, 26];
|
|
3114
|
+
case 23:
|
|
3115
|
+
error_12 = _a.sent();
|
|
3000
3116
|
return [4 /*yield*/, SlowQueryLogs.updateOne({ _id: logId }, {
|
|
3001
3117
|
$set: {
|
|
3002
3118
|
status: 'investigating',
|
|
3003
3119
|
auto_fix_status: 'failed',
|
|
3004
3120
|
auto_fix_result: {
|
|
3005
|
-
baseline_error: (
|
|
3121
|
+
baseline_error: (error_12 === null || error_12 === void 0 ? void 0 : error_12.message) || 'unknown'
|
|
3006
3122
|
},
|
|
3007
|
-
verification_notes: "Auto optimize baseline output comparison failed: ".concat((
|
|
3123
|
+
verification_notes: "Auto optimize baseline output comparison failed: ".concat((error_12 === null || error_12 === void 0 ? void 0 : error_12.message) || 'unknown error'),
|
|
3008
3124
|
last_triaged_by: 'auto-slow-query',
|
|
3009
3125
|
last_triaged_at: new Date()
|
|
3010
3126
|
}
|
|
3011
3127
|
})];
|
|
3012
|
-
case
|
|
3128
|
+
case 24:
|
|
3013
3129
|
_a.sent();
|
|
3014
3130
|
return [4 /*yield*/, this.maybeStopAutoOptimizeAfterFailure(logId, 'Auto optimize baseline output comparison failed')];
|
|
3015
|
-
case
|
|
3131
|
+
case 25:
|
|
3016
3132
|
_a.sent();
|
|
3017
3133
|
return [2 /*return*/];
|
|
3018
|
-
case 25:
|
|
3019
|
-
title = "Optimize slow query ".concat(log.slow_query_count_string || log.collection);
|
|
3020
|
-
description = this.buildSlowQueryAutoOptimizeDescription(log, app, baselineMetrics);
|
|
3021
|
-
_a.label = 26;
|
|
3022
3134
|
case 26:
|
|
3023
|
-
|
|
3135
|
+
title = "Optimize slow query ".concat(log.slow_query_count_string || log.collection);
|
|
3136
|
+
description = this.buildSlowQueryAutoOptimizeDescription(log, app, baselineMetrics, resolvedRepoSlug);
|
|
3137
|
+
_a.label = 27;
|
|
3138
|
+
case 27:
|
|
3139
|
+
_a.trys.push([27, 29, , 32]);
|
|
3024
3140
|
return [4 /*yield*/, this.createDashboardJob({
|
|
3025
3141
|
project: app._id,
|
|
3026
3142
|
title: title,
|
|
3027
3143
|
description: description,
|
|
3028
|
-
repo:
|
|
3029
|
-
path:
|
|
3144
|
+
repo: resolvedRepoSlug,
|
|
3145
|
+
path: resolvedRepoPath || undefined,
|
|
3030
3146
|
projectRoot: app.project_root || undefined
|
|
3031
3147
|
})];
|
|
3032
|
-
case 27:
|
|
3033
|
-
job = _a.sent();
|
|
3034
|
-
return [3 /*break*/, 31];
|
|
3035
3148
|
case 28:
|
|
3036
|
-
|
|
3149
|
+
job = _a.sent();
|
|
3150
|
+
return [3 /*break*/, 32];
|
|
3151
|
+
case 29:
|
|
3152
|
+
error_13 = _a.sent();
|
|
3037
3153
|
return [4 /*yield*/, SlowQueryLogs.updateOne({ _id: logId }, {
|
|
3038
3154
|
$set: {
|
|
3039
3155
|
status: 'investigating',
|
|
3040
3156
|
auto_fix_status: 'failed',
|
|
3041
|
-
verification_notes: "Auto optimize enqueue failed: ".concat((
|
|
3157
|
+
verification_notes: "Auto optimize enqueue failed: ".concat((error_13 === null || error_13 === void 0 ? void 0 : error_13.message) || 'unknown error'),
|
|
3042
3158
|
last_triaged_by: 'auto-slow-query',
|
|
3043
3159
|
last_triaged_at: new Date()
|
|
3044
3160
|
}
|
|
3045
3161
|
})];
|
|
3046
|
-
case
|
|
3162
|
+
case 30:
|
|
3047
3163
|
_a.sent();
|
|
3048
3164
|
return [4 /*yield*/, this.maybeStopAutoOptimizeAfterFailure(logId, 'Auto optimize wait failed')];
|
|
3049
|
-
case
|
|
3165
|
+
case 31:
|
|
3050
3166
|
_a.sent();
|
|
3051
3167
|
return [2 /*return*/];
|
|
3052
|
-
case
|
|
3168
|
+
case 32:
|
|
3053
3169
|
jobId = String((job === null || job === void 0 ? void 0 : job._id) || '').trim();
|
|
3054
|
-
if (!!jobId) return [3 /*break*/,
|
|
3170
|
+
if (!!jobId) return [3 /*break*/, 34];
|
|
3055
3171
|
return [4 /*yield*/, SlowQueryLogs.updateOne({ _id: logId }, {
|
|
3056
3172
|
$set: {
|
|
3057
3173
|
status: 'investigating',
|
|
@@ -3061,10 +3177,10 @@ var SlowQueryVerifier = /** @class */ (function () {
|
|
|
3061
3177
|
last_triaged_at: new Date()
|
|
3062
3178
|
}
|
|
3063
3179
|
})];
|
|
3064
|
-
case
|
|
3180
|
+
case 33:
|
|
3065
3181
|
_a.sent();
|
|
3066
3182
|
return [2 /*return*/];
|
|
3067
|
-
case
|
|
3183
|
+
case 34:
|
|
3068
3184
|
attemptStartedAt = new Date();
|
|
3069
3185
|
return [4 /*yield*/, SlowQueryLogs.updateOne({ _id: logId }, {
|
|
3070
3186
|
$inc: {
|
|
@@ -3087,71 +3203,71 @@ var SlowQueryVerifier = /** @class */ (function () {
|
|
|
3087
3203
|
last_triaged_at: new Date()
|
|
3088
3204
|
}
|
|
3089
3205
|
})];
|
|
3090
|
-
case
|
|
3206
|
+
case 35:
|
|
3091
3207
|
_a.sent();
|
|
3092
3208
|
return [4 /*yield*/, SlowQueryLogs.findOne({ _id: logId })];
|
|
3093
|
-
case
|
|
3209
|
+
case 36:
|
|
3094
3210
|
queuedLog = (_a.sent()) || log;
|
|
3095
3211
|
return [4 /*yield*/, this.notifyCustomerSlowQueryStatus('detected_auto_optimize_enabled', queuedLog)];
|
|
3096
|
-
case 36:
|
|
3097
|
-
_a.sent();
|
|
3098
|
-
_a.label = 37;
|
|
3099
3212
|
case 37:
|
|
3100
|
-
_a.trys.push([37, 39, , 42]);
|
|
3101
|
-
return [4 /*yield*/, this.waitForDashboardJobStop(jobId, this.config.autoOptimizeWaitTimeoutMs)];
|
|
3102
|
-
case 38:
|
|
3103
3213
|
_a.sent();
|
|
3104
|
-
|
|
3214
|
+
_a.label = 38;
|
|
3215
|
+
case 38:
|
|
3216
|
+
_a.trys.push([38, 40, , 43]);
|
|
3217
|
+
return [4 /*yield*/, this.waitForDashboardJobStop(jobId, this.config.autoOptimizeWaitTimeoutMs)];
|
|
3105
3218
|
case 39:
|
|
3106
|
-
|
|
3219
|
+
_a.sent();
|
|
3220
|
+
return [3 /*break*/, 43];
|
|
3221
|
+
case 40:
|
|
3222
|
+
error_14 = _a.sent();
|
|
3107
3223
|
return [4 /*yield*/, SlowQueryLogs.updateOne({ _id: logId }, {
|
|
3108
3224
|
$set: {
|
|
3109
3225
|
status: 'investigating',
|
|
3110
3226
|
auto_fix_status: 'failed',
|
|
3111
3227
|
auto_fix_result: {
|
|
3112
3228
|
job_id: jobId,
|
|
3113
|
-
error: (
|
|
3229
|
+
error: (error_14 === null || error_14 === void 0 ? void 0 : error_14.message) || 'timeout'
|
|
3114
3230
|
},
|
|
3115
|
-
verification_notes: "Auto optimize wait failed: ".concat((
|
|
3231
|
+
verification_notes: "Auto optimize wait failed: ".concat((error_14 === null || error_14 === void 0 ? void 0 : error_14.message) || 'timeout'),
|
|
3116
3232
|
last_triaged_by: 'auto-slow-query',
|
|
3117
3233
|
last_triaged_at: new Date()
|
|
3118
3234
|
}
|
|
3119
3235
|
})];
|
|
3120
|
-
case
|
|
3236
|
+
case 41:
|
|
3121
3237
|
_a.sent();
|
|
3122
3238
|
return [4 /*yield*/, this.maybeStopAutoOptimizeAfterFailure(logId, 'Auto optimize job state check failed')];
|
|
3123
|
-
case
|
|
3239
|
+
case 42:
|
|
3124
3240
|
_a.sent();
|
|
3125
3241
|
return [2 /*return*/];
|
|
3126
|
-
case 42:
|
|
3127
|
-
isRunning = false;
|
|
3128
|
-
_a.label = 43;
|
|
3129
3242
|
case 43:
|
|
3130
|
-
|
|
3131
|
-
|
|
3243
|
+
isRunning = false;
|
|
3244
|
+
_a.label = 44;
|
|
3132
3245
|
case 44:
|
|
3133
|
-
|
|
3134
|
-
return [
|
|
3246
|
+
_a.trys.push([44, 46, , 48]);
|
|
3247
|
+
return [4 /*yield*/, this.isDashboardJobRunning(jobId)];
|
|
3135
3248
|
case 45:
|
|
3136
|
-
|
|
3249
|
+
isRunning = _a.sent();
|
|
3250
|
+
return [3 /*break*/, 48];
|
|
3251
|
+
case 46:
|
|
3252
|
+
error_15 = _a.sent();
|
|
3137
3253
|
return [4 /*yield*/, SlowQueryLogs.updateOne({ _id: logId }, {
|
|
3138
3254
|
$set: {
|
|
3139
3255
|
status: 'investigating',
|
|
3140
3256
|
auto_fix_status: 'failed',
|
|
3141
3257
|
auto_fix_result: {
|
|
3142
3258
|
job_id: jobId,
|
|
3143
|
-
error: (
|
|
3259
|
+
error: (error_15 === null || error_15 === void 0 ? void 0 : error_15.message) || 'unknown'
|
|
3144
3260
|
},
|
|
3145
|
-
verification_notes: "Unable to confirm dashboard job state: ".concat((
|
|
3261
|
+
verification_notes: "Unable to confirm dashboard job state: ".concat((error_15 === null || error_15 === void 0 ? void 0 : error_15.message) || 'unknown error'),
|
|
3146
3262
|
last_triaged_by: 'auto-slow-query',
|
|
3147
3263
|
last_triaged_at: new Date()
|
|
3148
3264
|
}
|
|
3149
3265
|
})];
|
|
3150
|
-
case
|
|
3266
|
+
case 47:
|
|
3151
3267
|
_a.sent();
|
|
3152
3268
|
return [2 /*return*/];
|
|
3153
|
-
case
|
|
3154
|
-
if (!isRunning) return [3 /*break*/,
|
|
3269
|
+
case 48:
|
|
3270
|
+
if (!isRunning) return [3 /*break*/, 51];
|
|
3155
3271
|
return [4 /*yield*/, SlowQueryLogs.updateOne({ _id: logId }, {
|
|
3156
3272
|
$set: {
|
|
3157
3273
|
status: 'investigating',
|
|
@@ -3165,16 +3281,16 @@ var SlowQueryVerifier = /** @class */ (function () {
|
|
|
3165
3281
|
last_triaged_at: new Date()
|
|
3166
3282
|
}
|
|
3167
3283
|
})];
|
|
3168
|
-
case
|
|
3284
|
+
case 49:
|
|
3169
3285
|
_a.sent();
|
|
3170
3286
|
return [4 /*yield*/, this.maybeStopAutoOptimizeAfterFailure(logId, 'Auto optimize timed out')];
|
|
3171
|
-
case
|
|
3287
|
+
case 50:
|
|
3172
3288
|
_a.sent();
|
|
3173
3289
|
return [2 /*return*/];
|
|
3174
|
-
case
|
|
3175
|
-
case
|
|
3290
|
+
case 51: return [4 /*yield*/, AIDashboardJobs.findOne({ _id: jobId })];
|
|
3291
|
+
case 52:
|
|
3176
3292
|
finalJob = _a.sent();
|
|
3177
|
-
if (!(!finalJob || finalJob.phase !== 'COMPLETE' || finalJob.paused)) return [3 /*break*/,
|
|
3293
|
+
if (!(!finalJob || finalJob.phase !== 'COMPLETE' || finalJob.paused)) return [3 /*break*/, 55];
|
|
3178
3294
|
return [4 /*yield*/, SlowQueryLogs.updateOne({ _id: logId }, {
|
|
3179
3295
|
$set: {
|
|
3180
3296
|
status: 'investigating',
|
|
@@ -3189,15 +3305,15 @@ var SlowQueryVerifier = /** @class */ (function () {
|
|
|
3189
3305
|
last_triaged_at: new Date()
|
|
3190
3306
|
}
|
|
3191
3307
|
})];
|
|
3192
|
-
case
|
|
3308
|
+
case 53:
|
|
3193
3309
|
_a.sent();
|
|
3194
3310
|
return [4 /*yield*/, this.maybeStopAutoOptimizeAfterFailure(logId, 'Auto optimize job did not complete')];
|
|
3195
|
-
case
|
|
3311
|
+
case 54:
|
|
3196
3312
|
_a.sent();
|
|
3197
3313
|
return [2 /*return*/];
|
|
3198
|
-
case
|
|
3314
|
+
case 55:
|
|
3199
3315
|
publishOutcome = this.evaluateDashboardPublishOutcome(finalJob);
|
|
3200
|
-
if (!!publishOutcome.success) return [3 /*break*/,
|
|
3316
|
+
if (!!publishOutcome.success) return [3 /*break*/, 58];
|
|
3201
3317
|
return [4 /*yield*/, SlowQueryLogs.updateOne({ _id: logId }, {
|
|
3202
3318
|
$set: {
|
|
3203
3319
|
status: 'investigating',
|
|
@@ -3212,24 +3328,24 @@ var SlowQueryVerifier = /** @class */ (function () {
|
|
|
3212
3328
|
last_triaged_at: new Date()
|
|
3213
3329
|
}
|
|
3214
3330
|
})];
|
|
3215
|
-
case
|
|
3331
|
+
case 56:
|
|
3216
3332
|
_a.sent();
|
|
3217
3333
|
return [4 /*yield*/, this.maybeStopAutoOptimizeAfterFailure(logId, 'Auto optimize publish/deploy failed')];
|
|
3218
|
-
case
|
|
3334
|
+
case 57:
|
|
3219
3335
|
_a.sent();
|
|
3220
3336
|
return [2 /*return*/];
|
|
3221
|
-
case
|
|
3222
|
-
case 58:
|
|
3223
|
-
refreshedLog = (_a.sent()) || log;
|
|
3224
|
-
_a.label = 59;
|
|
3337
|
+
case 58: return [4 /*yield*/, SlowQueryLogs.findOne({ _id: logId })];
|
|
3225
3338
|
case 59:
|
|
3226
|
-
_a.
|
|
3227
|
-
|
|
3339
|
+
refreshedLog = (_a.sent()) || log;
|
|
3340
|
+
_a.label = 60;
|
|
3228
3341
|
case 60:
|
|
3229
|
-
|
|
3230
|
-
return [
|
|
3342
|
+
_a.trys.push([60, 62, , 65]);
|
|
3343
|
+
return [4 /*yield*/, this.runExplain(refreshedLog)];
|
|
3231
3344
|
case 61:
|
|
3232
|
-
|
|
3345
|
+
afterExplain = _a.sent();
|
|
3346
|
+
return [3 /*break*/, 65];
|
|
3347
|
+
case 62:
|
|
3348
|
+
error_16 = _a.sent();
|
|
3233
3349
|
return [4 /*yield*/, SlowQueryLogs.updateOne({ _id: logId }, {
|
|
3234
3350
|
$set: {
|
|
3235
3351
|
status: 'investigating',
|
|
@@ -3238,38 +3354,38 @@ var SlowQueryVerifier = /** @class */ (function () {
|
|
|
3238
3354
|
job_id: jobId,
|
|
3239
3355
|
publish_message: publishOutcome.message,
|
|
3240
3356
|
publish_branch: publishOutcome.branchName || '',
|
|
3241
|
-
validation_error: (
|
|
3357
|
+
validation_error: (error_16 === null || error_16 === void 0 ? void 0 : error_16.message) || 'unknown'
|
|
3242
3358
|
},
|
|
3243
|
-
verification_notes: "Post-deploy validation failed: ".concat((
|
|
3359
|
+
verification_notes: "Post-deploy validation failed: ".concat((error_16 === null || error_16 === void 0 ? void 0 : error_16.message) || 'unknown error'),
|
|
3244
3360
|
last_triaged_by: 'auto-slow-query',
|
|
3245
3361
|
last_triaged_at: new Date()
|
|
3246
3362
|
}
|
|
3247
3363
|
})];
|
|
3248
|
-
case
|
|
3364
|
+
case 63:
|
|
3249
3365
|
_a.sent();
|
|
3250
3366
|
return [4 /*yield*/, this.maybeStopAutoOptimizeAfterFailure(logId, 'Auto optimize post-deploy validation failed')];
|
|
3251
|
-
case
|
|
3367
|
+
case 64:
|
|
3252
3368
|
_a.sent();
|
|
3253
3369
|
return [2 /*return*/];
|
|
3254
|
-
case
|
|
3370
|
+
case 65:
|
|
3255
3371
|
afterMetrics = this.resolveExecutionMetrics(afterExplain.explainStats || {}, afterExplain.durationMs, afterExplain.stageSummaries || []);
|
|
3256
|
-
if (!this.config.autoOptimizeOutputCompareEnabled) return [3 /*break*/,
|
|
3257
|
-
if (!!baselineOutputFingerprint) return [3 /*break*/,
|
|
3372
|
+
if (!this.config.autoOptimizeOutputCompareEnabled) return [3 /*break*/, 71];
|
|
3373
|
+
if (!!baselineOutputFingerprint) return [3 /*break*/, 66];
|
|
3258
3374
|
outputEquivalence = {
|
|
3259
3375
|
passed: false,
|
|
3260
3376
|
reason: 'Baseline output fingerprint missing.',
|
|
3261
3377
|
mode: 'unknown'
|
|
3262
3378
|
};
|
|
3263
|
-
return [3 /*break*/,
|
|
3264
|
-
case 65:
|
|
3265
|
-
_a.trys.push([65, 67, , 70]);
|
|
3266
|
-
return [4 /*yield*/, this.captureOutputFingerprint(refreshedLog)];
|
|
3379
|
+
return [3 /*break*/, 71];
|
|
3267
3380
|
case 66:
|
|
3381
|
+
_a.trys.push([66, 68, , 71]);
|
|
3382
|
+
return [4 /*yield*/, this.captureOutputFingerprint(refreshedLog)];
|
|
3383
|
+
case 67:
|
|
3268
3384
|
afterOutputFingerprint = _a.sent();
|
|
3269
3385
|
outputEquivalence = this.compareOutputEquivalence(baselineOutputFingerprint, afterOutputFingerprint);
|
|
3270
|
-
return [3 /*break*/,
|
|
3271
|
-
case
|
|
3272
|
-
|
|
3386
|
+
return [3 /*break*/, 71];
|
|
3387
|
+
case 68:
|
|
3388
|
+
error_17 = _a.sent();
|
|
3273
3389
|
return [4 /*yield*/, SlowQueryLogs.updateOne({ _id: logId }, {
|
|
3274
3390
|
$set: {
|
|
3275
3391
|
status: 'investigating',
|
|
@@ -3280,9 +3396,9 @@ var SlowQueryVerifier = /** @class */ (function () {
|
|
|
3280
3396
|
publish_branch: publishOutcome.branchName || '',
|
|
3281
3397
|
baseline: baselineMetrics,
|
|
3282
3398
|
after: afterMetrics,
|
|
3283
|
-
output_equivalence_error: (
|
|
3399
|
+
output_equivalence_error: (error_17 === null || error_17 === void 0 ? void 0 : error_17.message) || 'unknown'
|
|
3284
3400
|
},
|
|
3285
|
-
verification_notes: "Post-deploy output comparison failed: ".concat((
|
|
3401
|
+
verification_notes: "Post-deploy output comparison failed: ".concat((error_17 === null || error_17 === void 0 ? void 0 : error_17.message) || 'unknown error'),
|
|
3286
3402
|
explain_plan: afterExplain.explainPlan,
|
|
3287
3403
|
explain_execution_stats: afterExplain.explainStats,
|
|
3288
3404
|
explain_generated_at: new Date(),
|
|
@@ -3296,13 +3412,13 @@ var SlowQueryVerifier = /** @class */ (function () {
|
|
|
3296
3412
|
}
|
|
3297
3413
|
}
|
|
3298
3414
|
})];
|
|
3299
|
-
case
|
|
3415
|
+
case 69:
|
|
3300
3416
|
_a.sent();
|
|
3301
3417
|
return [4 /*yield*/, this.maybeStopAutoOptimizeAfterFailure(logId, 'Auto optimize output comparison failed')];
|
|
3302
|
-
case
|
|
3418
|
+
case 70:
|
|
3303
3419
|
_a.sent();
|
|
3304
3420
|
return [2 /*return*/];
|
|
3305
|
-
case
|
|
3421
|
+
case 71:
|
|
3306
3422
|
validation = this.evaluateOptimizationOutcome(baselineMetrics, afterMetrics, outputEquivalence);
|
|
3307
3423
|
autoFixResult = {
|
|
3308
3424
|
job_id: jobId,
|
|
@@ -3313,7 +3429,7 @@ var SlowQueryVerifier = /** @class */ (function () {
|
|
|
3313
3429
|
output_equivalence: outputEquivalence,
|
|
3314
3430
|
validation: validation
|
|
3315
3431
|
};
|
|
3316
|
-
if (!!validation.passed) return [3 /*break*/,
|
|
3432
|
+
if (!!validation.passed) return [3 /*break*/, 74];
|
|
3317
3433
|
return [4 /*yield*/, SlowQueryLogs.updateOne({ _id: logId }, {
|
|
3318
3434
|
$set: {
|
|
3319
3435
|
status: 'investigating',
|
|
@@ -3333,13 +3449,13 @@ var SlowQueryVerifier = /** @class */ (function () {
|
|
|
3333
3449
|
}
|
|
3334
3450
|
}
|
|
3335
3451
|
})];
|
|
3336
|
-
case
|
|
3452
|
+
case 72:
|
|
3337
3453
|
_a.sent();
|
|
3338
3454
|
return [4 /*yield*/, this.maybeStopAutoOptimizeAfterFailure(logId, 'Auto optimize validation failed')];
|
|
3339
|
-
case
|
|
3455
|
+
case 73:
|
|
3340
3456
|
_a.sent();
|
|
3341
3457
|
return [2 /*return*/];
|
|
3342
|
-
case
|
|
3458
|
+
case 74: return [4 /*yield*/, SlowQueryLogs.updateOne({ _id: logId }, {
|
|
3343
3459
|
$set: {
|
|
3344
3460
|
status: 'optimized',
|
|
3345
3461
|
auto_fix_status: 'completed',
|
|
@@ -3358,13 +3474,13 @@ var SlowQueryVerifier = /** @class */ (function () {
|
|
|
3358
3474
|
}
|
|
3359
3475
|
}
|
|
3360
3476
|
})];
|
|
3361
|
-
case
|
|
3477
|
+
case 75:
|
|
3362
3478
|
_a.sent();
|
|
3363
3479
|
return [4 /*yield*/, SlowQueryLogs.findOne({ _id: logId })];
|
|
3364
|
-
case
|
|
3480
|
+
case 76:
|
|
3365
3481
|
optimizedLog = (_a.sent()) || log;
|
|
3366
3482
|
return [4 /*yield*/, this.notifyCustomerSlowQueryStatus('completed_success', optimizedLog, { notes: validation.reason })];
|
|
3367
|
-
case
|
|
3483
|
+
case 77:
|
|
3368
3484
|
_a.sent();
|
|
3369
3485
|
return [2 /*return*/];
|
|
3370
3486
|
}
|
|
@@ -3733,6 +3849,7 @@ var SlowQueryVerifier = /** @class */ (function () {
|
|
|
3733
3849
|
});
|
|
3734
3850
|
return result;
|
|
3735
3851
|
};
|
|
3852
|
+
SlowQueryVerifier.APP_SETTINGS_CACHE_TTL_MS = 10000;
|
|
3736
3853
|
return SlowQueryVerifier;
|
|
3737
3854
|
}());
|
|
3738
3855
|
exports.SlowQueryVerifier = SlowQueryVerifier;
|