fix(cluster): preserve file updates during in-flight pulls - #907
Conversation
Resolves puller.go: keep the Basekick-Labs#961 self-origin fast-path condition (RepullMissingSelfOrigin) and the Basekick-Labs#965 statLocal/presentAtSize pre-pull check, adding this branch's !request.force to the latter.
|
Thanks for this one. The in-flight supersession is the right shape for #798, and the tests are precise: all four that compile on main fail there, each on the path it names (the fifth references the new field). Your quarantine-test change is exactly the fix for #972, which I filed this morning before seeing your branch; please add I pushed a merge commit to your branch resolving the two conflicts with main (#961's self-origin fast-path condition and #965's Verdict: the supersession core is correct. I traced the interleavings of a finishing worker against a newer enqueue, an older one, High:
|
# Conflicts: # RELEASE_NOTES_2026.09.3.md
Signed-off-by: Efe Gökdemir <gokdemirefe1903@gmail.com>
…-pulls # Conflicts: # RELEASE_NOTES_2026.09.3.md # internal/cluster/filereplication/puller.go
|
I resolved the new conflict against current |
|
Thanks for the rework — the structural asks from the last round are genuinely done, and I checked them in the code rather than taking the description's word for it:
Build, Unfortunately there is a blocker, and it is the headline fix itself. Blocker:
|
|
Fixed in
|
…callback pair; move the note to 27.01.1 Round-3 review fold-in on top of the contributor's change (Basekick-Labs#907): - A forced content refresh on a shared backend would download the writer's own object from a peer and upload it back over the same key: a wasted transfer, and a regression of the object if a second rewrite raced the upload. Config.ForceContentRefresh, set by the coordinator for local storage only (as RepullMissingSelfOrigin is), turns a content-change signal into a plain registration elsewhere. Test: the FSM pair on a shared backend leaves a same-size copy alone and fetches nothing. - The puller tests drove the FSM's callback pair by hand; nothing pinned the producer. TestFSMContentChangeCallbackFiresAfterRegisterAndOnlyOnContent asserts register-then-content order, no content callback for an identical re-register or an unchanged update, the pair through the batch path, and no panic with the callback unwired. - The coordinator wires the content callback before the registration callback, so no apply can fire with only its non-forced half delivered. - Release note moved from the shipped 26.09.3 file to 27.01.1 and its exclusions corrected: the origin-node same-size case is gone since Basekick-Labs#984 re-stamps the rewriting node as origin; a rewrite learned from a snapshot restore is excluded instead (Basekick-Labs#1071); the delete-grace shape stays. - Stale comments (snapshot restores "fire no callbacks", "the real ManifestHas hook", a duplicated field comment) and a leftover single-case select in reconciliation_test.go.
|
Round 3 reviewed against the same matrix (Pattern 1 reader, old origin after a #984 rewrite, the rewriting node, queue full, stale catch-up page, snapshot restore, Pattern 2 with replication on). All four round-2 findings and the blocker are genuinely fixed, and each is now proven by a test that fails against the round-2 code: the callback-pair test ( Three Mediums remained, folded in on your branch (one commit on top of yours):
Merging on green CI. #972 closes with it; #1061 carried the same test fix and will be closed as superseded. |
Refs #798
Fixes #972
Problem
When the manifest advances a path while its pull is in flight, the puller could finish or retry stale work, miss the forced callback paired with ordinary registration, or discard a verified local generation before its replacement was ready.
Changes
ManifestHashook and update fixtures to useManifestEntry.This covers the in-flight replica update shape. Same-size rewrites on the origin node and delete-then-same-size re-registration during the delete grace window remain outside this PR.
Tests and validation
go test ./internal/cluster/filereplication ./internal/cluster/raft -count=1go test -race ./internal/cluster/filereplication -count=1go vet ./internal/cluster/filereplication ./internal/cluster/raftgofmtandgit diff --check