Repository navigation
Conversation
sdvz
marked this pull request as draft
November 11, 2026 18:14
sdvz
force-pushed
the
mock-quota-per-record-rejection
branch
from
November 11, 2026 18:44
e886e2f to
74c1a7c
Compare
sdvz
force-pushed
the
mock-quota-per-record-rejection
branch
from
November 11, 2026 18:58
74c1a7c to
c5bb729
Compare
The mock treated an over-quota batch as all or nothing. It reverted the batch and failed every record with 'quotaExceeded'. The real server keeps the records that fit and rejects the other records. A child next to a rejected parent gets 'referenceViolation' instead. The mock now gives the space that remains to the smallest records. It rejects the largest records with 'quotaExceeded'. It then rejects a record if the server does not hold the parent of that record. The orphan pass also runs on the normal save path, because a parent can fail for other reasons than quota. 'quota' is still a count of records. Size only puts the rejections in order inside a batch that does not fit.
The test sends a list with a large title and its small reminder in one batch. The list fails with 'quotaExceeded'. The reminder fails with 'referenceViolation'. The handler for 'referenceViolation' applies ON DELETE CASCADE to the reminder. It deletes a row that the server never held. The test fails on main. See pointfreeco#547.
sdvz
force-pushed
the
mock-quota-per-record-rejection
branch
from
November 11, 2026 23:09
c5bb729 to
726e49b
Compare
sdvz
marked this pull request as ready for review
November 11, 2026 23:13
4 of 5 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The second commit adds a test that fails on
main. It reproduces #547.The test drives
MockCloudDatabasewith ordinary writes and sends. It does not build a sync engine event by hand.The limit in the mock
MockCloudDatabase.modifyRecordstreated an over-quota batch as all or nothing. It reverted the batch and then failed every record withquotaExceeded.The real server keeps the records that fit and rejects the other records. A child record next to a rejected parent gets
referenceViolation, notquotaExceeded.The logs on #548 show this pair of errors:
The mock did not produce that pair. Therefore no test reached the
referenceViolationbranch ofhandleSentRecordZoneChangeswith a parent that never went to the server.saveRecordToDatabasealready rejects a child when the server does not hold the parent, but that check exempts a parent that is present inrecordsToSave. The exemption is correct when the save of the parent succeeds. It is wrong when that save fails, and nothing looked again.The changes
quotaExceeded.referenceViolation. This step repeats until no record changes, because a rejected child orphans its own children.quotaExceeded.The test
listAndReminderRejectedWhileStorageIsFullseeds one list (parent) with a large title and one small reminder (child). Then it sends the batch.The list fails with
quotaExceeded. The reminder fails withreferenceViolation. The handler applies theON DELETE CASCADEonreminders.remindersListID, and deletes a row that the server never held.Two expectations then fail. Line 502 expects the reminder row on the device. Line 518 expects the reminder to reach the server after the quota rises.
This test reproduces the fault on
e72164c, with #335, #571, #576 and #575 merged.Two questions
quotais a record count, so a batch that does not fit needs a rule for which records to reject. I order the rejections by encoded record size. That is the smallest change that gives a test a large parent that does not fit next to a small child that would fit. A byte count forquotais closer to real CloudKit. I will change it if you prefer that.sendPendingRecordZoneChangesreports an issue and returns unlesspendingRecordZoneChangesis not empty, orhasPendingUntrackedChangesis true. PersistedPendingRecordZoneChangerows satisfy neither check, and Always enqueue pending record changes when preparing batches #576 enqueues them later, inside batch preparation. Did I miss a way to drive that path from a test?