fix(core): open LMDB envs WithoutTls to stop reader slot leak (#664)#665
Open
gustav-fff wants to merge 1 commit into
Open
fix(core): open LMDB envs WithoutTls to stop reader slot leak (#664)#665gustav-fff wants to merge 1 commit into
gustav-fff wants to merge 1 commit into
Conversation
Default heed EnvOpenOptions opens envs in WithTls mode, where LMDB pins reader locktable slots to OS threads. Every thread that ever runs read_txn() permanently occupies a slot for the process lifetime, even after commit(). fff opens read txns from many threads (rayon workers, background_watcher, fff-lmdb-gc, git_status_worker, neovim main), so a handful of long-running nvim sessions exhaust the default 126-slot table and new nvim processes crash with MDB_READERS_FULL. Switch to read_txn_without_tls() — reader slots are now tied to MDB_txn objects and released on commit()/drop(). Regression test spawns 400 short-lived reader threads against a fresh FrecencyTracker; pre-fix it fails around thread 127 with MDB_READERS_FULL, post-fix all 400 succeed.
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.
Closes #664
Root cause
Default
heed::EnvOpenOptionsopens envs inWithTlsmode. In this mode LMDB ties reader locktable slots to OS threads instead ofMDB_txnobjects, so any thread that ever callsread_txn()occupies a slot for the entire process lifetime — the slot is not released oncommit()ordrop().fff opens read txns from many threads: rayon workers in
BACKGROUND_THREAD_POOL, thebackground_watcher, thefff-lmdb-gcthread,git_status_worker, and the neovim main thread.maxreadersdefaults to 126, so a handful of long-running nvim sessions burn through the entire reader table. New nvim sessions then hitMDB_READERS_FULLinopen_database_safe()atcrates/fff-core/src/dbs/lmdb.rs:210, which propagates out asError::DbStartReadTxnand ultimately manifests as the SIGSEGV in the reporter's log:clear_stale_readers()at env open only reclaims slots from dead processes, so live nvim instances happily hoard them.Fix
Open the env with
.read_txn_without_tls()(heed 0.22'sWithoutTlsmarker). Reader slots are now tied toMDB_txnobjects and released oncommit()/drop(). Everything downstream (FrecencyTracker,QueryTracker,DbHealthChecker,LmdbStore) is retyped toEnv<WithoutTls>; no runtime behavior changes for callers.Steps to reproduce
Pre-fix, on
main(1a8ef35):Actual (pre-fix): fails ~thread 127 with
MDB_READERS_FULL: Environment maxreaders limit reached.Expected: all 400 threads complete successfully.
In the wild: 7+ long-running nvim sessions with fff.nvim loaded, then open picker in a new nvim — crashes with SIGSEGV.
How verified
cargo test -p fff-search --lib— 98 pass.cargo test -p fff-search --test lmdb_reader_slot_leak— new regression test passes; revertinglmdb.rsfails the workspace to compile, confirming the trait plumbing is what enforces the flag.cargo check --workspace— clean.Automated triage via Gustav. Honk-Honk 🪿