Skip to content

[stable-35.0] Make change delivery acknowledgements safe against late and concurrent requests - #11062

Merged
mgallien merged 3 commits into
stable-35.0from
backport/11054/stable-35.0
Oct 14, 2026
Merged

mgallien merged 3 commits into
stable-35.0from
backport/11054/stable-35.0

Conversation

@backportbot

@backportbot backportbot Bot commented Oct 14, 2026

Copy link
Copy Markdown

Backport of PR #11054

@backportbot backportbot Bot added bug os: 馃崕 macOS Apple macOS, formerly also known as OS X 3. to review feature: 馃搧 file provider macOS File Provider Extension, more general also known as virtual file system. labels Oct 14, 2026
@backportbot backportbot Bot added this to the 35.0.1 milestone Oct 14, 2026
i2h3 added 3 commits October 14, 2026 14:34
removeChangeDeliverySessions(containerKey:) passed the lazy sequence
which `map` returns on Realm results to an `IN` predicate. Realm rejects
that with the Objective-C exception "IN clause requires an array of
items", so prime() and reset() raised it whenever a session still
existed for the container. `try?` does not catch it.

Without the fix, the new test reports this exception as an unexpected
failure.

Assisted-by: ClaudeCode:claude-opus-5-5
Signed-off-by: Iva Horn <iva.horn@nextcloud.com>
An enumerator acknowledges a change batch only after
finishEnumeratingChanges returns: on the main actor for updates and on
the reporting thread for trash deletions. Four enumerator tests asserted
the database state written by that acknowledgement right after
enumerateChanges() returned, so they failed whenever the assertion ran
first. Measured on master, testTrashChangeEnumeration failed 7 of 40
runs and testWorkingSetChangesBatchMixingUpdatesAndDeletions 2 of 30.

Wait for that state with an XCTNSPredicateExpectation instead, as
RemoteChangePropagationTests already does.

Assisted-by: ClaudeCode:claude-opus-5-5
Signed-off-by: Iva Horn <iva.horn@nextcloud.com>
An enumerator acknowledges a change batch after finishEnumeratingChanges
returns. File Provider can request the next batch before that, also on a
new enumerator, and that request acknowledges the reported batch itself.
Three defects made this unsafe:

- acknowledgeChangeDeliveryBatch acknowledged whichever batch was
  pending, with the caller's deletion list. A late acknowledgement thus
  committed the next batch before it was delivered, and that batch's
  deleted items were never removed. This also happened across sessions
  on a reused enumerator.
- It read the pending state outside the write transaction and applied
  the values it read inside it.
- A continuation anchor was looked up with two queries, for the
  committed and for the pending anchor. An acknowledgement committing in
  between moved the anchor from one to the other, both queries missed
  it, and the request failed with NSFileProviderErrorSyncAnchorExpired.

Identify a batch by its session and end position, check and apply its
acknowledgement in one write transaction, and derive its deletions from
the stored batch. Prepare a batch in one transaction as well and return
a batch which is already pending, so a repeated request replays it. Look
up a continuation anchor in one query. Remove the session when a stored
change cannot be decoded, so no undelivered batch stays pending.

testWorkingSetChangesResumeAcrossNewEnumeratorInstances failed 10 of 30
runs on master with NSFileProviderErrorSyncAnchorExpired and passed 40
of 40 with this change. The new late-acknowledgement tests in
ChangeDeliveryBufferTests and the stale-acknowledgement test in
FilesDatabaseManagerTests fail on master when adapted to its interface.
The single-query lookup has no deterministic test, only the loop above.

Assisted-by: ClaudeCode:claude-opus-5-5
Signed-off-by: Iva Horn <iva.horn@nextcloud.com>
@mgallien
mgallien enabled auto-merge October 14, 2026 12:34
@mgallien
mgallien force-pushed the backport/11054/stable-35.0 branch from 83f613f to 83950ff Compare October 14, 2026 12:34
@mgallien
mgallien merged commit 56dccf6 into stable-35.0 Oct 14, 2026
14 of 16 checks passed
@mgallien
mgallien deleted the backport/11054/stable-35.0 branch October 14, 2026 13:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

3. to review bug feature: 馃搧 file provider macOS File Provider Extension, more general also known as virtual file system. os: 馃崕 macOS Apple macOS, formerly also known as OS X

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants