Skip to content

fix(storage): flush pending debounced writes on unmount instead of discarding them - #725

Open
Matthew-Selvam wants to merge 1 commit into
libredb:mainfrom
Matthew-Selvam:fix/storage-sync-unmount-flush
Open

fix(storage): flush pending debounced writes on unmount instead of discarding them#725
Matthew-Selvam wants to merge 1 commit into
libredb:mainfrom
Matthew-Selvam:fix/storage-sync-unmount-flush

Conversation

@Matthew-Selvam

Copy link
Copy Markdown
Contributor

Summary

The useStorageSync unmount cleanup cleared the debounce timer without flushing, and pendingCollectionsRef — a per-mount useRef — was dropped with the component. An edit made within the 500ms debounce window of navigating away existed only in localStorage; the next mount's pullFromServer() then unconditionally overwrote localStorage with server data, destroying the write permanently and silently.

Fix

The cleanup now flushes whatever is pending before tearing down:

  • Guarded on serverModeRef — in local mode the queue is always empty and the PUT would be pointless work.
  • Guarded on a non-empty pending set — no spurious push when nothing is queued.
  • A failed post-teardown flush still re-queues its collections (existing behavior), and the existing !mountedRef.current guard already keeps it from arming stray retry timers — so the previous fix for the dead-hook retry loop is unaffected.

Test plan

  • New: a pending debounced write is flushed on unmount, not discarded — edit dispatched inside the debounce window, unmount, assert the PUT lands
  • New: unmount with nothing pending does not push — asserts the flush is conditional
  • Existing a push that fails after unmount does not leave a timer running still passes (in-flight push ≠ pending push; no double-send)

Found during a broader code review of the storage sync layer; no issue existed yet for it.

…scarding them

The unmount cleanup cleared the debounce timer without flushing, and
pendingCollectionsRef — a per-mount ref — was dropped with the component.
An edit made within the 500ms debounce window of navigating away existed
only in localStorage; the next mount's pullFromServer() then overwrote
localStorage with server data, destroying the write permanently.

The cleanup now flushes whatever is pending (server mode only, non-empty
queue only) before tearing down. A failed post-teardown flush still
re-queues its collections and the existing !mountedRef.current guard
keeps it from arming stray timers.
@codecov

codecov Bot commented Sep 9, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@cevheri cevheri added the loop:needs-moderator-action Flagged by the maintainer loop: suspicious content or a decision only a human can make label Sep 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

loop:needs-moderator-action Flagged by the maintainer loop: suspicious content or a decision only a human can make

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants