Skip to content

fix(sync): stop re-sending applied records and announce only Sync now - #1559

Merged
A-EDev merged 3 commits into
mainfrom
fix/sync2-resend-loop
Oct 29, 2026
Merged

A-EDev merged 3 commits into
mainfrom
fix/sync2-resend-loop

Conversation

@A-EDev

@A-EDev A-EDev commented Oct 29, 2026

Copy link
Copy Markdown
Collaborator

Summary

Two fixes from the owner's test, found in the server data and the phone's database.

  • Re-send loop: the phone uploaded its whole library about 8 times (ownSeq 191). sent.sentAt was bumped for all 13,166 watch_history keys at once.
    • Cause: applyBatches recorded the received line's hash as known. Desktop's canonical form of a record differs from Android's, so the next export saw every applied record as changed and pushed it back. Desktop did the same, and each push sent changed live frames.
    • Fix:
      • applyBatches now takes the device's own export of the affected collections. After a successful apply, it records the hash of this device's own form of each received key, never the received line's hash.
      • It also exports once before the apply. A key whose own form had changed since its last upload (a local edit not sent yet, kept by the merge) is left unknown, so that edit still goes out.
      • Unchanged hashes are not rewritten. The brains' 6 h throttle in outgoingBatches is unchanged.
  • Snackbar only after Sync now:
    • LinkedSyncWorker.syncSoon takes announce, passed as work input. Only Sync now sets it, and LinkedSync.syncNow(announce) emits "Received N changes from …" only then.
    • Background, live and on-leave runs keep the silent "Syncing with your linked devices…" notification and show no snackbar.

Related issue

Part of #1075 (linked devices). Stacked on #1558.

Change type

  • Bug fix
  • Feature
  • Refactor or maintenance
  • Build, packaging, or CI
  • Documentation

Validation

  • ./gradlew :app:assembleGithubDebug: ok
  • ./gradlew :app:testGithubDebugUnitTest: 4648 passed, 46 skipped, 0 failed. New in ChangeBatchesTest:
    • devices_whose_canonical_forms_differ_exchange_once_and_then_stay_quiet: a phone and a desktop that order the fields of the same record differently exchange once. Two more rounds then push nothing from either side, and both hold the same data. With the old received-hash rule, the phone's next push would carry the desktop's record back.
    • a_local_edit_not_uploaded_yet_still_goes_out_after_a_merge: a local edit that the merge keeps over an incoming record is still pushed.
    • SessionTest, PairingTest and the existing ChangeBatchesTest case now pass the export.
  • ./gradlew ktlintCheck: ok
  • python3 .github/scripts/nightly_notes.py --check: valid
  • I manually tested the affected behavior on an Android device or emulator. (Not run here: not against Desktop, and not the snackbar.)

Not covered by tests: the snackbar gating to Sync now.

Test device and Android version: none

Risk and compatibility

  • Each sender's batches now cost two exports of the received collections, one before and one after the merge. For a large watch history this adds export time to a sync that received data. Syncs that receive nothing are unchanged.

  • Devices already caught in the loop stop once both run this fix. Their next sync records their own forms as known.

  • The change does not introduce secrets, private data, or unexpected telemetry.

  • New user-facing text uses Android string resources. (None.)

  • Dependency and lockfile changes are intentional and limited to this PR. (None.)

  • Room schema changes include the required version bump and migration, or this PR does not change the Room schema. (No schema change.)

  • Breaking changes and upgrade steps are clearly documented. (None.)

@github-actions github-actions Bot added documentation Improvements or additions to documentation ui Compose UI, theming, or Material 3 surfaces labels Oct 29, 2026
@A-EDev
A-EDev changed the base branch from feat/sync2-live-status to main October 29, 2026 17:58
@github-actions github-actions Bot added sync Device-to-device sync build Gradle, dependencies, packaging, or R8 labels Oct 29, 2026
@github-actions github-actions Bot removed sync Device-to-device sync build Gradle, dependencies, packaging, or R8 labels Oct 29, 2026
@A-EDev
A-EDev merged commit 5253022 into main Oct 29, 2026
8 of 9 checks passed
@A-EDev
A-EDev deleted the fix/sync2-resend-loop branch October 29, 2026 21:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation ui Compose UI, theming, or Material 3 surfaces

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant