feat(api): fan an apply out to one operation per rollout member - #1270
Draft
aparajon wants to merge 7 commits into
Draft
feat(api): fan an apply out to one operation per rollout member#1270aparajon wants to merge 7 commits into
aparajon wants to merge 7 commits into
Conversation
An apply whose members are planned together shares one plan, and that is still the common case. When each member is planned against its own live schema, though, there is no single plan for the apply to point at. Add a nullable apply_operations.plan_id so a member can name the plan it executes, with PlanIDForOperation resolving to the parent apply's plan when the member has none. An operation with no plan on either row is not executable and now errors rather than resolving to a row ID no plan has. TargetOperationKey names the operation key for one target's work when a single apply addresses several targets, composing with the shard-scoped key so a sharded target still gets one key per shard. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
An apply resolves each rollout member to the plan its work is built from before building operations. Members of an environment whose members hold the same schema all carry the apply's own plan. A member that was planned against its own live schema carries its own plan, looked up by member id and bound to the head SHA the apply's plan was created for, so plans from an earlier push of the same pull request are never picked up. A member with no plan for that review round fails apply creation. The apply's plan describes a different target's schema, so substituting it would run DDL that target was never planned for. Operations are grouped by member, and a member is its deployment and target together, so two targets of one deployment each get their own operation for a given (namespace, shard, table) rather than sharing one. An operation names a plan of its own only when it runs a different plan than its apply. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The trusted control-plane enqueue path holds no `Databases` config, so resolving the member planning contract there fails and apply creation with it. A single member is the plan's own primary: it runs the apply's plan under either contract, and no sibling's plan could be substituted for it, so the contract lookup is unnecessary work at that point. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The error identified the operation by its internal numeric row ID, which is not a triage handle an operator can look up. Name the operation by the identifiers that route it instead. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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.
Why this matters
An apply builds one operation per deployment and runs the apply's single plan on all of them. For an environment whose members were planned independently, that means every member runs the primary's DDL — DDL written for a different target's schema. This is the apply half of the multi-target contract: each member executes the plan it was actually planned from.
It also closes a latent collision that exists independently of the
targets:spelling. The sharded operation group key was built from the deployment alone, so two members sharing a deployment would collide on a key and one member's work would be filed under the other's.What it does
Resolves every rollout member to a plan before building operations, then keys the operations by member:
(namespace, shard, table)instead of one target's work being folded into the other's.How it moves us toward the northstar
This is the step A4a's multi-target rejection was waiting on: the apply composer now consumes the full
ResolveTargetsresult, dispatching one operation per member against the plan that member was planned from, instead of collapsing the result to a single route.Opened by Claude (Fable 5).