Skip to content

fix(sync): catch-up Background scope, superseded-rename adopt, smoke HOME isolation#1

Open
DRNKNMaster wants to merge 7 commits into
mainfrom
ci/catch-up-fixes-validation
Open

fix(sync): catch-up Background scope, superseded-rename adopt, smoke HOME isolation#1
DRNKNMaster wants to merge 7 commits into
mainfrom
ci/catch-up-fixes-validation

Conversation

@DRNKNMaster

Copy link
Copy Markdown
Contributor

CI validation of three fixes for smoke regressions that surfaced after the ws-reliability-poll-floor work (which turned smoke/smoke-macos red on scenarios 08, 17, 21, 22, 28, and — after the first fix pass — 32).

Fixes

  • fix(sync): catch-up reconcile pulls with Background scope — a catch-up (dirty) reconcile pushes first but applies its pull with Background materialize scope and does tombstone cleanup instead of the full sweep, keeping the offline-delete resurrection guard while preserving the push-first conflict-copy behavior. Fixes 32-offline-delete-no-resurrect.
  • fix(sync): adopt a superseded local rename into the winning path — when push_local's rename/move is superseded (another device won), the same sync cycle's pull-apply mv's the loser's diverged folder onto the winning path instead of orphaning it and later pushing a duplicate node. Fixes 17-rename-folder.
  • test(smoke): isolate each scenario with a fresh per-scenario HOME — each scenario gets a fresh HOME (empty sync.db) reusing the once-registered device tokens, so mounts stop accumulating and daemon boot has no catch-up storm. Fixes the foreground-sync starvation behind 22-realtime-sync.

Local validation

  • 277 unit tests pass.
  • Full smoke suite 33/33 both with per-scenario HOME isolation and under mount accumulation (17 passes even where the slow multi-mount sync guarantees the resume-catchup's second scan fires, proving the rename fix is deterministic, not timing).

This PR exists to run smoke and smoke-macos on real CI. Not intended to merge here — the change lands via the private monorepo and the mirror.

A catch-up (dirty) reconcile now push-first but applies its pull with
Background materialize scope and does tombstone cleanup instead of the full
materialize sweep. This keeps the offline-delete resurrection guard (a file
deleted locally while offline is not re-downloaded when another device pushed
a new_version for that node) while preserving the push-first conflict-copy fix
for un-pushed edits. Explicit `valv sync` stays Full scope.
Give each scenario a fresh HOME_A/HOME_B (empty sync.db) reusing the
once-registered device tokens, so mounts stop accumulating across scenarios
and daemon boot has no catch-up storm. Fixes the foreground-sync starvation
behind the realtime scenario's fast-fail. Suffix is the scenario number only
to keep the daemon Unix socket path within the platform sun_path limit.
When push_local's rename/move for a node is superseded (another device won
the race), record the loser's on-disk path. The same sync cycle's pull-apply,
when it would otherwise materialize the winner as a fresh dir and orphan the
loser, instead mv's the loser folder onto the winning path. Prevents the
orphan being pushed later as a duplicate node, and carries any children created
under it during the pause. Consulted only when a superseded rename/move
occurred, so single-writer rename/move paths are unaffected.
Re-check paused after the dirty-reconcile debounce sleep. A reconcile
scheduled just before POST /pause otherwise ran ~1s into the pause and pushed
(a delete, or a half-staged rename that beat the peer to the server). Continue
without taking the flag so post_resume's catch-up reconciles after resume.
Rename the file on disk (fs-events paused, guarded by old.exists and
!new.exists) after submitting the op and upserting the mirror, closing the
mirror-ahead-of-disk window where a background reconcile pushed a duplicate
create and deleted the original.
wait_for_file_on_device/wait_for_node_at_path/wait_for_no_live_node_at_path
called an assert that does exit 1 from an if condition, aborting the whole
script on the first failed poll instead of retrying. Use non-exiting checks.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant