[Fix] Keep uploading when a write races the write checkpoint - #1055
[Fix] Keep uploading when a write races the write checkpoint#1055bean1352 wants to merge 6 commits into
Conversation
🦋 Changeset detectedLatest commit: 824eb52 The changes in this PR will be included in the next version bump. This PR includes changesets to release 7 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
Shouldn't the new write also have triggered a crud trigger? If we change private async crudUploadLoop(signal: AbortSignal, options: ResolvedSyncOptions): Promise<void> {
while (!signal.aborted) {
const crudChangeNotification = this.crudUploadNotifier.waitForNotification(signal);
await Promise.all([
// Start the initial CRUD upload on connect. Then, keep polling until we're done.
this._uploadAllCrud(signal, options),
this.delayRetry(signal, options.crudUploadThrottleMs)
]);
await crudChangeNotification;
}
} |
As far as I can tell the write does trigger the notification (my mistake), so registering the wait earlier should not change anything. I tried your version against the new test and the upload still stops. |
What's wrong
When the CRUD queue looks empty, the upload loop requests a write checkpoint.
updateLocalTargetre-reads the queue inside a write transaction and returns false if it finds a row, but it also returns false when there is nothing left to upload. The loop treated both the same way and stopped with the row still inps_crud, even thoughupdateLocalTargethad already seen it and logged "New data uploaded since write checkpoint N - need new write checkpoint".The sync core then refuses every checkpoint with "Could not apply checkpoint due to local data".
The fix
Ask the adapter whether CRUD is still pending before stopping, and go round again if it is. This covers both branches where
updateLocalTargetreports a race, includingsequence updated.The retry is delayed by
crudUploadThrottleMs.Tests
One test makes the queue read miss the row once with CRUD notifications left working, which reproduces the sequence in the logs from the original report. The other keeps that read missing and checks the retry stays near the throttle rate. Each one fails without the part of the fix it covers.
Still open
Why
nextCrudItem()misses a committed row on React Native. It reads throughthis.db.getOptionalwhileupdateLocalTargetchecks insidewriteTransaction, so a stale read snapshot in the connection pool is the obvious candidate.AI disclosure
I used Opus 5 to help research the original bug report, narrow down where the fault could be, and apply the fix. I reviewed and supervised the work.