Skip to content

test: search-index concurrency for rebuild, queries, and lock order#139

Merged
wpak-ai merged 8 commits into
masterfrom
test/search-index-concurrency
Jul 23, 2026
Merged

test: search-index concurrency for rebuild, queries, and lock order#139
wpak-ai merged 8 commits into
masterfrom
test/search-index-concurrency

Conversation

@clean6378-max-it

@clean6378-max-it clean6378-max-it commented Jul 22, 2026

Copy link
Copy Markdown
Collaborator

Closes #136

Sprint #7 adds tests/test_search_index_concurrency.py and changes utils/search_index.py so the background refresh worker can shut down cleanly in tests. The worker gets a cooperative stop event, reset_background_for_tests joins the daemon thread, and startup runs under _index_lock. Without that, full pytest could leave a search-index-refresh thread running. We hit that on Windows: lock-order tracing picked up events from a stray worker.

The suite exercises rebuild plus query overlap. One test runs multiple readers against a writer that keeps calling build_search_index(..., force=True), with a barrier each round. Another runs start_search_index_background while queries run and new session files appear; it checks that mutator-only terms show up in the index and that more than one refresh cycle runs. Lock nesting from #138 is recorded during a forced rebuild and checked against the doc (no index lock on the build path, usability only under the build lock), with a small negative control on the checker. Other cases cover index_locked on OperationalError, empty vs locked, live-scan fallback when the index is locked with no hits, and partial hits when a later batch sees lock contention. The stress test also counts reader rounds where the sentinel term actually appears in hits and fails if that count is zero, so it cannot pass as a no-crash test when every round is locked or query_ok is false.

After a join attempt (and a warning if the thread is still alive past the timeout), reset_background_for_tests clears _background_started, releases the background lock fd, and clears _background_stop so the next test can start a worker. write_session and index_patches moved into tests/conftest.py for reuse from test_search_index.py and the concurrency file.

Quick check: pytest tests/test_search_index_concurrency.py -q --no-cov (eight tests). CI full pytest is the real gate. Builds on #138; the suite should fail if lock nesting regresses.

Summary by CodeRabbit

Summary by CodeRabbit

  • Bug Fixes / Improvements

    • Improved search index background worker shutdown and synchronization to prevent lifecycle/race issues.
    • Standardized query result metadata for empty/invalid/error cases and correctly flags “index locked” situations.
    • More consistent session title fallback and hit construction during indexing and querying.
  • Tests

    • Added concurrency and background-refresh tests to validate rebuild/query overlap and partial-results behavior.
    • Added lock-order contract checks and safeguards distinguishing “database locked” from absent terms.
    • Shared search-index test helpers across test modules.

@coderabbitai

coderabbitai Bot commented Jul 22, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds concurrency-focused search-index tests and updates background-worker lifecycle and query error handling. The suite covers rebuilds, background refreshes, lock ordering, locked-index reporting, legitimate empty results, live-scan fallback, and partial indexed results.

Changes

Search index concurrency validation

Layer / File(s) Summary
Background worker and query-state control
utils/search_index.py
Coordinates worker shutdown and restart state, standardizes empty query results, reports database locks, and centralizes index metadata constants.
Indexed search test harness
tests/conftest.py, tests/test_search_index_concurrency.py, tests/test_search_index.py
Adds shared session/cache helpers, isolated worker fixtures, seeded indexed data, sentinel assertions, and updated background-worker test setup.
Lock-order instrumentation and validation
tests/test_search_index_concurrency.py
Captures lock events during index builds and validates permitted and forbidden nesting sequences.
Concurrent rebuild and refresh coverage
tests/test_search_index_concurrency.py
Exercises queries during forced rebuilds, background refreshes, and session mutations while checking termination, exceptions, and indexed visibility.
Query locking and fallback semantics
tests/test_search_index_concurrency.py
Validates locked-index errors, absent-term results, live-scan fallback, and preservation of partial hits.

Estimated code review effort: 4 (Complex) | ~45 minutes

Possibly related PRs

Suggested reviewers: timon0305, wpak-ai

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 4.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title is concise and accurately summarizes the concurrency-focused search-index changes.
Linked Issues check ✅ Passed The PR implements the requested concurrency suite, lock-order checks, and locked-index/live-scan behavior from #136.
Out of Scope Changes check ✅ Passed The production and test-support changes appear necessary to enable the concurrency tests and lifecycle handling.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch test/search-index-concurrency

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@tests/test_search_index_concurrency.py`:
- Around line 182-246: Update test_queries_during_background_refresh to use a
poll interval that guarantees multiple background refresh opportunities during
the mutator loop, and ensure the test cleanup stops and joins the background
worker before returning. Extend reset_background_for_tests or add test-local
cleanup using the existing background lifecycle symbols, while preserving the
reader/mutator assertions.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 6072df99-3db2-4c96-854c-cc61c7a49a60

📥 Commits

Reviewing files that changed from the base of the PR and between bcde11d and b8d7e39.

📒 Files selected for processing (1)
  • tests/test_search_index_concurrency.py

Comment thread tests/test_search_index_concurrency.py

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@utils/search_index.py`:
- Around line 814-837: The reset logic in the background worker lifecycle must
retain ownership while termination is unconfirmed. In utils/search_index.py
lines 814-837, when the thread remains alive after joining, keep
_background_started, _background_thread, and _background_lock_fd unchanged,
leave _background_stop set, and prevent replacement startup; only clear
ownership and release the lock after termination is confirmed. In
utils/search_index.py lines 702-711, synchronize thread startup with reset so a
published but not-yet-started worker cannot be orphaned.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: f938e7d1-064b-4bf7-803c-3631b5f7a3c8

📥 Commits

Reviewing files that changed from the base of the PR and between e20e37b and 44a8f29.

📒 Files selected for processing (4)
  • tests/conftest.py
  • tests/test_search_index.py
  • tests/test_search_index_concurrency.py
  • utils/search_index.py
🚧 Files skipped from review as they are similar to previous changes (1)
  • tests/test_search_index_concurrency.py

Comment thread utils/search_index.py Outdated
@timon0305

Copy link
Copy Markdown
Collaborator

"Tests-only goal" / "does not change production search-index code" is inaccurate: utils/search_index.py is +58/-53 with a real background-worker lifecycle change (cooperative stop Event + thread creation moved inside _index_lock). Please reword to reflect the production race fix.

Comment thread utils/search_index.py Outdated
Comment thread tests/test_search_index_concurrency.py
@clean6378-max-it

Copy link
Copy Markdown
Collaborator Author

"Tests-only goal" / "does not change production search-index code" is inaccurate: utils/search_index.py is +58/-53 with a real background-worker lifecycle change (cooperative stop Event + thread creation moved inside _index_lock). Please reword to reflect the production race fix.

updated PR description now

@clean6378-max-it clean6378-max-it self-assigned this Jul 23, 2026
Comment thread tests/conftest.py Outdated
@clean6378-max-it
clean6378-max-it requested a review from wpak-ai July 23, 2026 15:30
Comment thread tests/test_search_index_concurrency.py
@clean6378-max-it
clean6378-max-it requested a review from wpak-ai July 23, 2026 16:33
@wpak-ai
wpak-ai merged commit f0fbb8e into master Jul 23, 2026
16 checks passed
@wpak-ai
wpak-ai deleted the test/search-index-concurrency branch July 23, 2026 17:49
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.

claude-code-chat-browser: concurrency test suite for rebuild, pointer swap, and query

3 participants