Preserve API watch event ordering during mutations - #275
Merged
David Negstad (danegsta) merged 1 commit intoSep 24, 2026
Merged
Conversation
Prevent concurrent mutations of the same API resource type from publishing watch events out of storage commit order. Add deterministic coverage that reproduces the Tilt filepath storage race and verifies the middleware preserves ordering. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
David Negstad (danegsta)
requested review from
Karol Zadora-Przylecki (karolz-ms)
and
a balanced review from Copilot
September 24, 2026 02:20
Copilot started reviewing on behalf of
David Negstad (danegsta)
September 24, 2026 02:21
View session
Contributor
There was a problem hiding this comment.
Copilot review overview
🔵 Needs a closer look
The concurrency change affects mutation throughput and ordering across every API resource and warrants final human review.
Review effort: Balanced
Findings: None
What changed in this PR
Serializes API mutations per group/resource to keep Tilt storage commits and watch events consistently ordered.
Changes:
- Adds mutation-ordering middleware to the API server handler chain.
- Shares locks across parent resources, versions, and subresources.
- Adds middleware and real filepath-storage concurrency tests.
| File | Description |
|---|---|
internal/apiserver/apiserver.go |
Registers the ordering middleware. |
internal/apiserver/ordered_resource_mutation_handler.go |
Implements per-resource mutation serialization. |
internal/apiserver/ordered_resource_mutation_handler_test.go |
Tests lock scope and mutation detection. |
internal/apiserver/ordered_resource_mutation_storage_test.go |
Reproduces and verifies watch-event ordering. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
This was referenced Sep 24, 2026
Open
Karol Zadora-Przylecki (karolz-ms)
approved these changes
Sep 24, 2026
David Negstad (danegsta)
deleted the
danegsta-fix-finalizer-shutdown-race
branch
September 24, 2026 17:38
Member
Author
|
/backport to release/0.26 |
|
Started backporting to release/0.26: https://github.com/microsoft/dcp/actions/runs/36035788308 |
|
David Negstad (@danegsta) backport PR couldn't be created automatically, please create the backport PR manually! |
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.
Concurrent mutations in Tilt's filepath storage can commit in resource-version order but publish their watch events in the opposite order. During shutdown, this can regress a controller cache from a deleting object to an older non-deleting object, preventing finalizer cleanup and causing resource cleanup to time out.
This change serializes mutating requests per API group/resource around the complete storage handler operation. Parent-resource and subresource mutations share the same lock because they publish to the same watch stream, while reads and mutations of different resource types remain concurrent.
The tests include a deterministic reproduction using Tilt's actual filepath storage. It commits a status update, delays its notification, and then commits deletion, proving that the unprotected storage can publish the higher-resource-version deletion before the stale status event. The same experiment verifies that the middleware preserves storage and watch ordering.
This is a local containment measure. The underlying ordering guarantee should ultimately be enforced by Tilt so persistence and watch publication cannot be reordered.
Validation
make lintmake testgo test -count 1 -race ./internal/apiserver -timeout 180s