fix: share the per-repo SCIP LMDB env; clear frozen C# index error state - #214
Merged
Conversation
…rebuilds and adapters
Every SCIP operation (C#/TS query, watcher rebuild, lazy find-refs,
ref-cache prewarm) opened its own short-lived TrackedEnv on db_path/scip.
LMDB allows one open env per directory per process, so any overlap — a
rebuild starting while a lazy find-refs held its env for minutes —
failed the loser with `LMDB double-open prevented` (observed live on
HUSQ.Aprimo-231210: rebuild failed at the exact moment a 35s-old
find-refs env was alive; the resulting red `C#!` froze on the TUI).
All opens now route through get_or_open_shared_env (Weak-ref cache in
lmdb_registry): concurrent users get the same Arc<TrackedEnv>, writers
serialise on LMDB's single-writer mutex, readers never block, C# and TS
share one env (5 named DBs pre-created once per session). The cache
never keeps an env alive: last Arc drop still closes + frees the slot,
so remove_repo's holder-drain is unaffected. scip_meta hoisted to
constants (was a duplicated literal in both adapters).
Review-fixes:
- [Design] get_or_open_shared_env doc: closures run under the cache shard lock and must not re-enter (self-deadlock on same shard)
- [Debt] csharp.rs comments still asserted the old per-caller-env invariant ("opens its own env", "must drop before ... opens its own env") — rewritten for the shared env
repo_statuses_lightweight() prefers the cached csharp_index_status over its on-disk probe, so an Error entry outlives the repo itself: a closed repo has no watcher left to retry a rebuild or emit Succeeded, and the red `C#!` renders forever (observed: HUSQ.Aprimo-209169 stuck red for days after losing one double-open race before 2026-08-18). evict_idle_repos and close_repo now clear the status+error entries; the fallback probe (helper available + index exists -> Ready) restores the on-disk truth. Regression test with EnvRestore + serial pins eviction clearing both maps. CHANGELOG: entry for both stages under the pending [1.3.4] section (assumption: extend the existing undated top section, matching where PR #213 added its entry after the 1.3.5 auto-bump). Review-fixes: - [Debt] clear_csharp_index_state doc overclaimed "called whenever a repo's stores close" — remove_repo deliberately skips it (unregistered alias = display-unreachable entry); doc now states the asymmetry
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Every SCIP symbol-index operation (C#/TS query, watcher rebuild, lazy find-refs, ref-cache prewarm) opened its own short-lived LMDB env on db_path/scip. LMDB allows only one open env per directory per process, so any overlap between a long-lived query (a lazy find-refs can hold its env for minutes on a large solution) and a watcher-triggered rebuild failed the loser with "LMDB double-open prevented". Observed live: HUSQ.Aprimo-231210's C# rebuild failed mid-session, and HUSQ.Aprimo-209169's failure froze as a permanent red C#! in the TUI status view (repo_statuses_lightweight prefers the cached error over its on-disk probe, and a closed repo has no watcher left to retry or clear it).
Fix
Verification
CHANGELOG entry added under the [1.3.4] pending heading.