Skip to content

fix: centralize DB open/create logic, fix force-reindex on missing DB#54

Merged
flupkede merged 8 commits into
developfrom
features/lmdb_access_limitation
May 18, 2026
Merged

fix: centralize DB open/create logic, fix force-reindex on missing DB#54
flupkede merged 8 commits into
developfrom
features/lmdb_access_limitation

Conversation

@flupkede

Copy link
Copy Markdown
Owner

Summary

Centralize all LMDB database open/create logic into a single try_open_stores helper on ServeState, eliminating 4 duplicate code paths. Fix the bug where POST /repos/{alias}/reindex?force=true returned HTTP 500 when the .codesearch.db directory had been externally deleted.

Changes

New: try_open_stores helper (src/serve/mod.rs:1319)

  • Single entry point for all open LMDB stores operations
  • create_if_missing=false: fails fast if DB missing; tries write -> readonly -> Conflicted fallback
  • create_if_missing=true: creates fresh DB if absent; no readonly fallback
  • Returns OpenedStores::Write (caller registers) or OpenedStores::Readonly (already registered)

Bug fix: force-reindex on deleted DB

  • reindex_handler force branch now calls try_open_stores(.., true) when FSW is not running
  • Previously called get_or_open_stores which blocked on missing DB -> HTTP 500

4 call sites unified

  • warmup_repo slow path: create_if_missing=false
  • get_or_open_stores slow path: create_if_missing=false
  • reindex_handler force branch: create_if_missing=true (bug fix)
  • add_repo_handler: create_if_missing=true

Bonus fixes

  • stop_fsw returns None for Readonly repos (prevents force-reindex against readonly-locked stores)
  • add_repo_handler concurrent guard cancels token + removes repos entry on 409
  • touch_access doc updated (warmup_repo now calls it)
  • TrackedEnv runtime guard prevents LMDB double-open from MCP fallback paths

Testing

  • cargo check pass
  • cargo clippy -- -D warnings pass
  • cargo test --lib: 390 passed, 12 ignored, 0 failed
  • QC gate (fmt + check + clippy + test) pass

flupkede added 8 commits May 18, 2026 13:57
Replace `index_quiet()` background task (which opens its own LMDB handle) with
inline `SharedStores::new()` + background `force_reindex_with_stores()`. This
prevents the race where `get_or_open_stores()` tries to open a second LMDB
handle on the same path while `index_quiet` holds the first one.

Key changes:
- Open SharedStores inline (fast, just LMDB+Tantivy handle creation)
- Store as RepoState::Write immediately (prevents double-open from other handlers)
- Spawn force_reindex_with_stores + vector build + restart_fsw in background
- Add active_reindexes guard for concurrency protection
- Clean up config entry on failure
In serve mode, with_vector_store_read_for() no longer falls back to opening a standalone VectorStore when shared_stores read fails. This prevents "environment already opened" errors from LMDB.
- stop_fsw now returns None for Readonly repos instead of passing
  readonly stores into the force-reindex path. Callers fall through
  to try_open_stores(create_if_missing=true) which fails clearly
  when the write lock is held.
- touch_access doc: warmup_repo now calls touch_access after
  successful warmup; update doc to reflect current callers.
@flupkede flupkede merged commit 1527dd6 into develop May 18, 2026
4 checks passed
@flupkede flupkede deleted the features/lmdb_access_limitation branch May 18, 2026 20:58
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