fix(05-review): WR-04 collect delete changes after db.delete to avoid race in sync fan-out
This commit is contained in:
@@ -239,9 +239,15 @@ export async function syncCalendar(
|
||||
// touches another calendar or the other household member's rows (BUG B).
|
||||
// When the server returns zero events, prune the whole calendar's cache.
|
||||
// NOTIF-03: collect deleted uids for the onChanges callback.
|
||||
//
|
||||
// WR-04: pre-capture the rows to delete BEFORE the DB delete so we know what
|
||||
// was removed, then push changes AFTER the delete completes. This ensures the
|
||||
// onChanges payload only describes events that are truly gone from the cache —
|
||||
// not events that may have been re-fetched in a concurrent poll.
|
||||
let pendingDeleteRows: Array<{ uid: string; title: string | null }> = []
|
||||
if (onChanges && seenUids.length > 0) {
|
||||
// Find cached uids that are about to be pruned so we can emit delete changes
|
||||
const cachedRows = await db
|
||||
pendingDeleteRows = await db
|
||||
.select({ uid: calendarEvents.uid, title: calendarEvents.title })
|
||||
.from(calendarEvents)
|
||||
.where(
|
||||
@@ -250,13 +256,6 @@ export async function syncCalendar(
|
||||
notInArray(calendarEvents.uid, seenUids),
|
||||
),
|
||||
)
|
||||
for (const row of cachedRows) {
|
||||
changes.push({
|
||||
uid: row.uid,
|
||||
title: row.title ?? null,
|
||||
operation: 'delete',
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
if (seenUids.length > 0) {
|
||||
@@ -267,6 +266,16 @@ export async function syncCalendar(
|
||||
await db.delete(calendarEvents).where(eq(calendarEvents.calendarId, cal.id))
|
||||
}
|
||||
|
||||
// Collect delete changes AFTER the DB delete (WR-04: avoids race where the same
|
||||
// uid is re-inserted by a concurrent poll before onChanges fires).
|
||||
for (const row of pendingDeleteRows) {
|
||||
changes.push({
|
||||
uid: row.uid,
|
||||
title: row.title ?? null,
|
||||
operation: 'delete',
|
||||
})
|
||||
}
|
||||
|
||||
// 6. Fire onChanges callback if provided and there are changes (NOTIF-03).
|
||||
// Fire-and-forget: sync correctness must not depend on push success.
|
||||
if (onChanges && changes.length > 0) {
|
||||
|
||||
Reference in New Issue
Block a user