Skip to content

claude-code-chat-browser: document search-index lock-acquisition order and threading model #135

Description

@clean6378-max-it

Sprint Item

#6 of 8 — Medium severity — land first Wednesday (PR 1 of 2; docs-only)

Block Relations

Blocked by — (independent of cursor-browser #1–#5)
Blocks #7 — concurrency suite asserts the documented lock order
Repo/day Independent of #1–#5

Calendar Day

Wednesday, July 22, 2026 (PR 1 of 2 — docs-only; land before #7)

Planned Effort

5 story points (Medium) — sprint item #6

Problem

utils/search_index.py declares four module-global locks with no documented acquisition order, threading model, or single-worker assumption:

  • _index_lock (line 57)
  • _index_build_lock (line 58)
  • _background_lock_fd (line 60)
  • _usability_cache_lock (line 62)

The deployment surface — background refresh thread, atomic pointer swap, one-writer-per-host — is undocumented. A contributor cannot reason about safe lock nesting, and there is no stated single-worker constraint, so a multi-worker WSGI deploy would silently violate the design.

Goal

One docs-only PR that records the four locks and their permitted acquisition order (or the non-nested-by-design contract), documents the threading model and single-worker constraint, and adds a multi-worker WSGI warning to a deployment note. This doc becomes the invariant the concurrency suite (item #7) enforces.

Docs-only discipline (Week 3 retro learning): keep this PR docs-only. Do not fold in the concurrency test suite — that ships separately as test/search-index-concurrency (item #7).

Scope

Part A — lock inventory + order

  • Record all four locks and their permitted acquisition order, or state explicitly that they are non-nested by design and must stay so.
  • Describe current usage precisely:
    • _index_build_lock wraps build_search_index (line 521)
    • _index_lock guards _background_started
    • _usability_cache_lock guards the usability cache
    • _background_lock_fd is the cross-process advisory lock (lines 641-663)
    • _publish_active_index does the swap + prune (lines 187-219)

Part B — threading model

  • Document: request threads read; one daemon thread writes; the active index is published by an atomic search_index.active swap (readers see old or new, never partial).
  • State the single-worker constraint, with a multi-worker WSGI warning in a deployment note.

Part C — where it lives

  • Update docs/architecture.md (around line 148) and/or README.md (lines 56-72) as the home for the lock-order + threading section; deployment note where the multi-worker warning belongs.

Out of scope

Acceptance Criteria

  • Docs record the four locks and their permitted acquisition order (or the non-nested-by-design contract, stated as a must-stay-so rule).
  • The threading model is documented: request threads read, one daemon writes, active index published by atomic search_index.active swap.
  • The single-worker constraint is documented, with a multi-worker WSGI warning in a deployment note.
  • Docs-only — no source-behavior change.
  • The order documented here is the one the concurrency suite (UI/UX design overhaul: theme, animations, interactive components (#5) #7) asserts (goes red on regression).
  • CI green (lint/link checks); PR approved by at least 1 reviewer.

Verification

cd C:\Users\Jasen\CppAliance\claude-code-chat-browser
.\.venv\Scripts\Activate.ps1
# docs-only: link/lint checks
  • Review: the documented order matches actual usage at utils/search_index.py:57-63,187-219,521,641-693.

Metadata

Metadata

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions