Skip to content

fix(xapian): invalidate getDocData cache after index reload#1990

Open
piratefinn wants to merge 1 commit into
masterfrom
piratefinn/fix-getdocdata-cache
Open

fix(xapian): invalidate getDocData cache after index reload#1990
piratefinn wants to merge 1 commit into
masterfrom
piratefinn/fix-getdocdata-cache

Conversation

@piratefinn

Copy link
Copy Markdown
Contributor

Root cause

getDocData in searchservice.ts uses a single-doc cache (currentXapianDocId / currentDocData) to avoid redundant Xapian lookups when the display requests the same document multiple times per row render.

After a flag change (seen, flagged, answered), the worker adds/removes the term, commits, and fires indexUpdatedSubject. The main thread syncs from IndexedDB via FS.syncfs, reloads the Xapian database, and fires indexReloadedSubject. But the cache was never invalidated, so getDocData returned stale data for the last-accessed docid.

This affected all flag-based display updates: bold/unread state, flag icons, answered indicators. The Angular 16 upgrade (commit 50b8e5d) shifted rendering timing enough to expose the pre-existing cache bug.

Fix

One line: clear currentXapianDocId after reloadXapianDatabase() and before indexReloadedSubject.next(), so consumers always read fresh data from the reloaded database.

Tests

5 new tests in searchservice.spec.ts, all running on master (no dependency on accessible-table or MessageDisplay code):

  • Seen flag visible after reload
  • Flagged flag visible after reload
  • Multiple flags (seen + flagged) in one reload
  • Cache still works between calls without reload (no perf regression)
  • Different docid triggers fresh lookup without reload (existing behavior preserved)

Full suite: 262 passing, 0 failing.

Scope

Fix lives entirely in searchservice.ts. Works on master and on the accessible-table branch. Tests are importable to either branch.

getDocData uses a single-doc cache (currentXapianDocId /
currentDocData) to avoid redundant lookups when the canvastable
requests the same document multiple times per row.

After a flag change (seen, flagged, answered), the worker adds or
removes a term, commits, and fires indexUpdatedSubject. The main
thread syncs from IndexedDB, reloads the Xapian database, and fires
indexReloadedSubject. But the cache was never invalidated, so
getDocData returned stale data for the last-accessed docid.

This affected all flag-based display updates: bold/unread state,
flag icons, answered indicators. The Angular 16 upgrade shifted
rendering timing enough to expose the pre-existing cache bug.

Fix: clear currentXapianDocId after reloadXapianDatabase() and
before indexReloadedSubject.next(), so consumers always read fresh
data from the reloaded database.

Tests cover seen flag, flagged flag, multiple flags at once, and
verify the cache still provides its performance benefit between
reload cycles.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant