feat(storage): add cutover-claim predicate FindNextApplyOperationCutover#398
Merged
Conversation
Cutover counterpart to FindNextApplyOperation: claims a row parked at waiting_for_cutover and drives it to cutting_over only when its turn comes in deployment order. Unlike the copy gate's barrier relaxation, the cutover "done" set is completed-only so the atomic swaps never overlap and run strictly in order, with the on_failure "continue" exemption and pending-stop guard mirrored from the copy gate. A stale in-flight cutover is re-leased without an ordering gate so a dead driver's swap can be recovered.
There was a problem hiding this comment.
Pull request overview
Adds a new MySQL storage “claim” primitive to safely advance apply_operations into the cutover phase, mirroring the existing copy-phase claim logic while enforcing stricter deployment-order semantics for cutover.
Changes:
- Extends the
ApplyOperationStoreinterface withFindNextApplyOperationCutoverfor cutover-phase claiming. - Implements
FindNextApplyOperationCutoverin the MySQL store usingSELECT … FOR UPDATE SKIP LOCKEDunderREAD COMMITTED, supporting both “start parked cutover” and “recover stale in-flight cutover” paths. - Adds a focused test suite that pins ordering, stop-guard behavior, on_failure “continue” exemption, and stale-recovery semantics.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| pkg/storage/storage.go | Adds the new storage interface method with detailed contract documentation. |
| pkg/storage/mysqlstore/apply_operations.go | Implements the atomic cutover-claim + lease-rotation transaction and stale recovery path. |
| pkg/storage/mysqlstore/apply_operations_test.go | Adds coverage to validate cutover ordering gates, stop behavior, on_failure exemption, and stale recovery. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
aparajon
approved these changes
Jun 17, 2026
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.
What
Adds
FindNextApplyOperationCutover, the storage claim primitive for the cutover phase — the counterpart toFindNextApplyOperation(the copy gate). It atomically claims a row parked atwaiting_for_cutover, transitions it tocutting_over, and rotates a fresh operation lease, usingFOR UPDATE SKIP LOCKEDunderREAD COMMITTED.Two claim paths:
deployment_order: a later deployment may cut over only once every earlier sibling has reachedcompleted. Carries theon_failure: continueexemption and the pending-stop guard, mirroring the copy gate.cutting_over/revert_windowrow whose heartbeat went stale is re-leased without changing state, with no ordering gate (the swap already started).Why
The copy gate relaxes the deployment-order barrier once an earlier sibling reaches the cutover barrier, so copies can overlap. The cutover (the high-risk atomic swap) must not: its "done" set is completed-only so swaps run strictly one at a time, in order. This primitive is additive and dormant — nothing claims it yet — and is the first slice of ordered cutover (OC-1).