51 lines
1.5 KiB
JavaScript
51 lines
1.5 KiB
JavaScript
const RECOVERABLE_KINDS = new Set(["CHUNK_LOAD_FAILURE", "DEPLOY_MISMATCH"]);
|
|
|
|
/**
|
|
* @typedef {{action: "reload-once", releasePair: string} |
|
|
* {action: "support", reason: string}} ChunkRecoveryDecision
|
|
*/
|
|
|
|
/**
|
|
* @param {{
|
|
* failureKind: string,
|
|
* manifestLoaded: boolean,
|
|
* currentBuildId: string,
|
|
* currentReleaseId: string,
|
|
* activeBuildId: string,
|
|
* activeReleaseId: string,
|
|
* storage: import("../ports/storage-port.js").StoragePort
|
|
* }} input
|
|
* @returns {ChunkRecoveryDecision}
|
|
*/
|
|
export function decideChunkRecovery(input) {
|
|
if (!RECOVERABLE_KINDS.has(input.failureKind)) {
|
|
return { action: "support", reason: "not-recoverable" };
|
|
}
|
|
if (!input.manifestLoaded) {
|
|
return { action: "support", reason: "manifest-unavailable" };
|
|
}
|
|
if (
|
|
input.activeBuildId === input.currentBuildId &&
|
|
input.activeReleaseId === input.currentReleaseId
|
|
) {
|
|
return { action: "support", reason: "same-release" };
|
|
}
|
|
|
|
const releasePair =
|
|
`${input.currentBuildId}/${input.currentReleaseId}` +
|
|
`->${input.activeBuildId}/${input.activeReleaseId}`;
|
|
const guard = input.storage.read("CHUNK_RELOAD_GUARD");
|
|
if (!guard.ok) {
|
|
return { action: "support", reason: "guard-read-failed" };
|
|
}
|
|
if (guard.value === releasePair) {
|
|
return { action: "support", reason: "reload-already-attempted" };
|
|
}
|
|
|
|
const recorded = input.storage.write("CHUNK_RELOAD_GUARD", releasePair);
|
|
if (!recorded.ok) {
|
|
return { action: "support", reason: "guard-write-failed" };
|
|
}
|
|
return { action: "reload-once", releasePair };
|
|
}
|