Release the shell from a candidate engine that fails after it attached

The shell's scene part detaches it too, so a candidate failing in a later part (a layer's drawing, Cockpit clouds) leaves the shell free for the working engine instead of refusing every later attach. StyleManager.attachScene releases what it built when it throws, and one detach runs at a time. The controls phase awaits its parts, and a failed attachment no longer forces handoff off for the parts it releases. scripts/qa-app-once.mjs now also rolls back from a Navara candidate whose layer attachment fails.
This commit is contained in:
German Khokhlov committed 2026-11-03 19:45:34 +04:00
1 parent 58c8a481ed
commit d86047fe8f
12 files changed
+229 -76

No files matched your search

+1
View File
@@ -2662,6 +2662,7 @@
"src/app/tools.js",
"src/app/sessionVoice.js",
"src/app/sceneParts.js",
"src/app/shellPart.js",
"src/app/viewer.js",
"src/sky/starrySky.js",
"src/sky/stars.js",
+40
View File
@@ -320,6 +320,46 @@ try {
'ids changed after the rollback',
idDifference(boot.ids, final.ids),
);
// A candidate failing after the shell attached to it: a layer's
// drawing refuses to attach on Navara. The shell lets go of the failed
// globe and Cesium attaches again; the next switch works.
await page.evaluate(() => {
window.__qaDataRefused = false;
const module =
window.__godsEyeView.dataManager.layers.get('earthquakes').module;
const attach = module.attachRenderer;
module.attachRenderer = function () {
module.attachRenderer = attach;
window.__qaDataRefused = true;
return Promise.reject(new Error('QA data attach failure'));
};
});
const beforeDataFailure = await page.evaluate(() => history.length);
await requestEngine(page, 'navara');
await page.waitForFunction(() => window.__qaDataRefused === true, {
timeout: 60_000,
});
await waitReady(page, 'cesium');
const afterDataFailure = await readSession(page);
report.dataFailure = {
ids: idDifference(boot.ids, afterDataFailure.ids),
counters: afterDataFailure.counters,
history: (await page.evaluate(() => history.length)) - beforeDataFailure,
};
check(
Object.keys(report.dataFailure.ids).length === 0 &&
report.dataFailure.history === 0,
'a candidate failing in the data part changed the session',
report.dataFailure,
);
await switchEngine(page, 'navara');
await switchEngine(page, 'cesium');
check(
Object.keys(idDifference(boot.ids, (await readSession(page)).ids))
.length === 0,
'ids changed after the data-part failure',
);
}
report.errors = errors;
check(errors.length === 0, 'page errors', errors);