Skip to content

Files: hold a shared write lease in sync writers and share upload #505

Open

Description

@veryCrunchy

Problem

#498 adds an account-scoped Files write fence: while a delete is in flight or its outcome still needs verification, in-app writes to that path, its folder and its contents are refused with a typed reason. Background sync and virtual-file writeback do not go through that fence. ADAPTER_ARCHITECTURE.md ("Files delete write fence") documents this boundary.

The sync remote-tree adapters mutate the server directly:

  • Android: AndroidFileSyncRemoteTree.writeFile, delete, chunked upload, and the directory replacement move.
  • Desktop: DesktopFileSyncRemoteTree.writeFile/writeFileCancellable, createDirectory, delete, move, moveReplacing, and the backup moves and deletes, all through executeMutation.

If one of these writers publishes a file or folder inside a folder whose recursive DELETE is in flight, the server can remove the newly synchronized data while the sync engine records its mutation as committed. A later reconciliation can then treat the item as deleted remotely, so user data can be lost without a visible conflict. Raised in review of #498; kept out of that PR because it changes sync engine behavior.

The same check-then-publish window exists in Android share upload. #498 checks the fence before each file in AndroidIncomingShareUploadWorker, but a delete can still start between that check and the file being published.

Proposed direction

  • Add one shared write lease to the account fence: a writer holds a lease for the target path for the duration of each operation, and delete claims that overlap a held lease are rejected or wait until it is released. Use it for both the sync writers and Android share upload.

  • Pass the narrow FileWriteFence for the sync pair's account into both remote-tree adapters, from the same per-account fence registry the app uses.

  • Before each remote mutation, check the fence for the target path, and for a move both source and destination. Hold a write claim for the duration of the operation, so a Files delete of an overlapping path cannot start while a sync write is in flight, and the reverse.

  • When blocked, the sync operation must defer and retry later through the engine's existing durable retry. It must never drop the change, mark it committed, or turn it into a conflict copy only because of the fence.

  • Keep the existing ETag preconditions and conflict handling unchanged.

Acceptance criteria

  • Android and desktop sync remote mutations check the account fence and hold a per-operation write lease.
  • Android share upload holds a write lease for each file from the fence check through publication, so no overlapping delete can start in between.
  • A sync write into a folder with an in-flight or refresh-required delete is deferred, not sent, and completes after the block lifts.
  • A Files delete overlapping a running sync write waits or is refused with a typed reason, never interleaves.
  • Deferral survives process death through the existing sync recovery path, with no lost or duplicated changes.
  • Deterministic tests for deferral, overlap in both directions, account isolation, cancellation and restart; Android unit tests execute.
  • ADAPTER_ARCHITECTURE.md no longer lists background sync and virtual-file writeback as outside the fence.

Activity

  1. added
    bugSomething isn't working
    priority:P1Required for the pre-release product experience
    area:files-syncFiles, offline storage, transfer, and synchronization
    type:reliabilityCorrectness, crash prevention, recovery, and data safety
    platform:androidAndroid-specific implementation or validation
    platform:desktopDesktop-specific implementation or validation
    on Oct 13, 2026
  2. changed the title [-]Sync: hold the Files delete write fence in background sync writers[/-] [+]Files: hold a shared write lease in sync writers and share upload[/+] on Oct 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:files-syncFiles, offline storage, transfer, and synchronizationbugSomething isn't workingplatform:androidAndroid-specific implementation or validationplatform:desktopDesktop-specific implementation or validationpriority:P1Required for the pre-release product experiencetype:reliabilityCorrectness, crash prevention, recovery, and data safety

    Type

    No type

    Projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions