Repository navigation
fix(appproto): a plan on the wire is read as one plan - #1841
Merged
Merged
Conversation
writePlan read the plan, its rev and the chargers' windows in three calls. cmd/ftw's Rev reads the planner again, and PlanChargers takes its own snapshot, so a replan between them mixed two plans in one message: the new plan's windows under the old plan's rev (run 40115146270, TestAPlugInReachesAStreamingPhoneAsAPlan: "pushed rev 1 after 1"), or the old slots under the new rev. The box now reads the plan again when it moved during the read, at most twice more. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
…lots Review: the planner also swaps in a copy of the plan that carries its shadow result, so a read can move twice. The test now reports a plan without slots instead of panicking on it, and the changeset no longer says always. Co-Authored-By: Claude Opus 5.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.
A real bug that a flaky
cmd/ftwtest showed. Run 40115146270 (PR #1822), race job:Cause
writePlanbuilds a plan message from three reads:Plans.Latest()for the slots,Plans.Rev()for the revision, andPlanChargers.PlanChargers()for each charger's windows. In the box,appPlans.Rev()reads the planner's latest plan again, andappPlanChargerstakes its ownPlanSnapshot(). When a replan publishes between those reads, one message carries two plans:Fix
readPlanreads the three, then checks that the planner's latest plan is still the one it started from. If it moved, it reads again, at most twice more. A replan moves the pointer once, and once more when the planner swaps in the copy that carries its shadow result, so three reads cover it. Every write to the planner's latest plan stores a fresh allocation, so when the first and last reads see the same pointer, every read in between saw it too. Patch changeset.Evidence
TestAReplanDuringTheReadSendsOnePlanpublishes a new plan on the fake box during the read, as the planner can. On master it fails withplan rev 1 with slots from 1760000000000, want rev 2 from 1760000060000, with the new windows already in the chargers. On this branch it passes.go test -race ./internal/appproto/passes.go test -race -count=3 -run 'Plan|AppLink' ./cmd/ftw/passes, including the test that failed.go vet ./...passes.Review
An independent review (Sonnet) found no bug. It checked that every write to
s.lastis a fresh allocation, so the pointer check holds, and that lock order, skip-same, agent ids and truncation are unchanged. Its notes are in the second commit: the shadow swap named in the comment, the test reports a plan without slots instead of panicking, and the changeset no longer says "always".It also found a separate, older issue, not changed here.
appPlans.Rev(cmd/ftw/app_link.go) callsLatest()before it takesrevMu. With two sessions on the sameappPlans, a slow reader can movelastGenback and bump the rev twice for one replan. The cost is a jump in rev and one extra push, not a mixed plan.🤖 Generated with Claude Code