Repository navigation
Conversation
… command Singleton handover matched previous containers by role name. A scheduler renamed from scheduler to cron, or a singleton that became a scalable worker, started its replacement beside the old container. The old one was removed only at commit, after the web container was live, so both ran and a scheduled task could fire twice. The rollout now plans the handover from both deployments' frozen role definitions. A new role continues a previous one only when the name, the singleton flag and the command all match. The command is the only part of a role that says what it runs. A name alone is not enough: two singletons can swap names, and a worker name can take over a scheduler's command. Every other new role is changed. A previous singleton that no new role continues is outgoing. When some role changed, it is stopped and retained after the unchanged workers pass their startup check, and before any changed role starts. With no changed role, this comparison identifies no replacement, so outgoing singletons remain running until commit. On failure, an outgoing singleton is restored only after every changed role is confirmed removed. An unchanged worker that cannot be removed does not block the restore. runtimeRoleRolloutDeps now passes the previous roles to the rollout. Without previous definitions, only same-name handover applies, as before. The openship.json reference describes the handover rules. Refs oblien#1253
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Singleton handover now decides which roles continue by name, effective singleton status and exact command text. A singleton whose workload no new role continues is stopped and retained before any added or changed role starts. On failure, it is restored only after every added or changed role is confirmed removed.
Motivation
Singleton handover matched previous containers by role name (
role-rollout.ts). Two changes bypassed it:schedulertocronstarted beside the old container. The old one was removed only atcommit(), after the web container was live.In the run reported in #1253, the renamed
cronand the oldschedulerboth ran for 23.3 s, and both fired the 06:34 tick.A name alone cannot identify a workload. Two singletons can swap names, and an existing worker name can take over a scheduler's command. Both would still run one workload twice if continuity were decided by name and kind.
Related issue
Refs #1253. With the previous deployment's saved role definitions, this change handles each case the issue lists. Without them, the old same-name behaviour remains (see Limits).
Changes
packages/platform
src/engine/modules/deployments/role-rollout.ts:planSingletonHandover(roles, previousRoles, previous). A new role continues a previous role only when the name, the singleton flag and thecommandall match.commandis the only part of a role definition that says what it runs. The image and the environment come from the deployment and are shared by every role. Every other new role is changed.RoleRolloutDepsgains optionalpreviousRoles. Without them, only same-name handover applies, exactly as before.stopRetaininghelper. Its cancellation check, timeout and error message are unchanged.src/engine/modules/deployments/role-runtime.ts:runtimeRoleRolloutDepspassespreviousRolesto the rollout. It already received them for the teardown timeout.apps/web
content/docs/reference/openship-json.mdx: the singleton paragraphs now state the continuation rule, the outgoing order, the restore rule and the fallback when saved definitions are missing. They no longer limit stop-first handover to a role that keeps its name.apps/api
test/modules/deployments/role-rollout.test.ts: 18 new cases.schedulertocron) is stopped after the unchanged worker is checked, and beforecronstarts.aruns A and oldbruns B, then newaruns B and newbruns A. Both old singletons stop before either new one starts. On abort, neither is restored while removal of either new singleton is uncertain. Both are restored when both are removed.schedulerruns A and oldqueueruns B, then the newqueueruns A with two replicas. The old scheduler stops before either replica starts. On abort, it is restored only when every replica is removed.cronis removed, stays stopped whencroncannot be removed, and is restored when only the unchanged worker cannot be removed.cron.test/modules/deployments/role-runtime.test.ts: one new case. ThroughruntimeRoleRolloutDepsand the real rollout, a renamed scheduler's stop precedes its replacement's start.test/e2e/runtime-roles.e2e.test.ts: one new Docker case, the [Bug]: Renaming a singleton role runs the old and new containers together #1253 repro. Releasefrunsscheduler, and releasegrenames it tocron. Before commit, the old scheduler isexitedandcronruns. The scheduler log endsstart-f, stop-f, start-g. The test passespreviousRolesto the rollout directly. The unit case above covers the forwarding inruntimeRoleRolloutDeps.Verification
With
role-rollout.tsfrommain, 14 of the new unit cases fail. The new Docker case fails withexpected 'running' to be 'exited', because the old scheduler still runs besidecron.Mutation checks. Each mutant fails at least one test:
command(name and singleton flag only)runtimeRoleRolloutDepsdoes not passpreviousRolesbun format: every changed file is Prettier-clean, exceptopenship-json.mdx, which was not Prettier-clean before this change. Prettier reports no change on the lines I edited there.Behaviour notes
Limits
Checklist