rollbridge 0.1.48 → 0.1.49

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": "rollbridge",
3
- "version": "0.1.48",
3
+ "version": "0.1.49",
4
4
  "description": "Zero-downtime process supervisor and local traffic switcher for deploy-managed apps.",
5
5
  "keywords": [
6
6
  "deploy",
package/src/daemon.js CHANGED
@@ -1936,7 +1936,9 @@ export default class RollbridgeDaemon {
1936
1936
  if (candidate.releasePath !== transition.candidateReleasePath || candidate.revision !== transition.candidateRevision || ownerConfigDigest(candidate.config) !== transition.configDigest) {
1937
1937
  throw new Error(`Generation transition candidate ${candidate.releaseId} does not retain its exact path, revision, and config authority`)
1938
1938
  }
1939
- if (candidate.state !== "draining" && candidate.state !== "stopped") throw new Error(`Failed candidate ${candidate.releaseId} must be retired before accepting a retired incumbent`)
1939
+ const recoverableCandidateStates = transition.phase === "retiring_previous" ? ["starting", "draining", "stopped"] : ["draining", "stopped"]
1940
+
1941
+ if (!recoverableCandidateStates.includes(candidate.state)) throw new Error(`Failed candidate ${candidate.releaseId} must be retiring or retired before accepting a retired incumbent`)
1940
1942
  if (this.activeRelease !== previous) throw new Error(`Previous release ${previous.releaseId} is not the authoritative proxy target`)
1941
1943
  const activationConfig = previous.config.processes.find((processConfig) => processConfig.lifecycle.activateCommand !== undefined)
1942
1944
  const coordinator = activationConfig ? previous.getProcesses(activationConfig.id)[0]?.process : undefined
@@ -830,6 +830,7 @@ test("explicit recovery stops the exact failed candidate and fences degraded inc
830
830
  transition.phase = "retiring_previous"
831
831
  transition.error = "Release v1 retirement quiescence failed: quiet command exited non-zero with status 1"
832
832
  transition.compensationError = undefined
833
+ candidate.state = "starting"
833
834
  await daemon.checkpointGenerationTransition()
834
835
  const legacyRecovery = await exactRecovery()
835
836