core: handle case when updating item while a push is ongoing

This commit is contained in:
Abdullah Atta
2024-05-06 22:04:04 +05:00
parent 63f44d6fbc
commit ac96354b4c
4 changed files with 84 additions and 3 deletions

View File

@@ -46,6 +46,7 @@ class Collector {
for (const itemType of SYNC_ITEM_TYPES) {
const collectionKey = SYNC_COLLECTIONS_MAP[itemType];
const collection = this.db[collectionKey].collection;
let pushTimestamp = Date.now();
for await (const chunk of collection.unsynced(chunkSize, isForceSync)) {
const items = await this.prepareChunk(chunk, key);
if (!items) continue;
@@ -54,8 +55,20 @@ class Collector {
await collection.update(
chunk.map((i) => i.id),
{ synced: true },
{ sendEvent: false }
{
sendEvent: false,
// EDGE CASE:
// Sometimes an item can get updated while it's being pushed.
// The result is that its `synced` property becomes true even
// though it's modification wasn't yet synced.
// In order to prevent that, we only set the `synced` property
// to true for items that haven't been modified since we last ran
// the push. Everything else will be collected again in the next
// push.
condition: (eb) => eb("dateModified", "<=", pushTimestamp)
}
);
pushTimestamp = Date.now();
}
}
}

View File

@@ -226,7 +226,14 @@ export class SQLCollection<
async update(
ids: string[],
partial: Partial<SQLiteItem<T>>,
options: { sendEvent: boolean } = { sendEvent: true }
options: {
sendEvent: boolean;
condition?: ExpressionOrFactory<
DatabaseSchema,
keyof DatabaseSchema,
SqlBool
>;
} = { sendEvent: true }
) {
if (!this.sanitizer.sanitize(this.type, partial)) return;
@@ -237,6 +244,7 @@ export class SQLCollection<
await tx
.updateTable<keyof DatabaseSchema>(this.type)
.where("id", "in", chunk)
.$if(!!options.condition, (eb) => eb.where(options.condition!))
.set({
...partial,
dateModified: Date.now(),