Files
amethyst/quartz/src
Claude 1027324da8 perf: run post-migration FTS reindex in the background
The v2->v3 upgrade previously rebuilt the entire full-text index inside
the migration transaction. With a large cache (e.g. 100k events) that
blocked every DB operation behind a single long transaction at startup:
the app appeared frozen, risked an ANR if reached on the main thread, and
— because it was all-or-nothing with the version bumped only on success —
a crash, kill, or one malformed cached row could roll everything back and
retry from scratch on every launch (worst case: an unrecoverable boot loop)
while the WAL ballooned.

Decouple the reindex from the migration:

- The migration now only recreates the empty FTS table and writes a
  persistent `fts_reindex` marker holding a progress cursor, then bumps the
  version. It is cheap and atomic.
- A background coroutine (Dispatchers.IO, cancelled on close()) backfills the
  index from event_headers in small committed batches via useWriter, so live
  relay inserts/queries interleave between batches instead of waiting.
- Backfill is idempotent (INSERT OR IGNORE), resumable (cursor persists, so a
  kill resumes on next launch), and resilient (a row that fails to parse/index
  is skipped while the cursor still advances — no stuck retries).

Search is merely degraded (partial results) until the backfill finishes,
never blocked. Adds a test covering backfill + marker clearing.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RFdWREvyvixRXnmNXNzmmN
2026-06-18 18:42:09 +00:00
..
2026-05-12 19:27:12 -04:00