Repository navigation
Files: hold a shared write lease in sync writers and share upload #505
Description
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 throughexecuteMutation.
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
FileWriteFencefor 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.mdno longer lists background sync and virtual-file writeback as outside the fence.
Metadata
Metadata
Assignees
Labels
Type
Projects
- StatusShow more project fieldsTodo
Activity
[-]Sync: hold the Files delete write fence in background sync writers[/-][+]Files: hold a shared write lease in sync writers and share upload[/+]