feat: assorted improvements for CLI/daemon to be resilient and ergonomic#72
Merged
feat: assorted improvements for CLI/daemon to be resilient and ergonomic#72
Conversation
Three root causes fixed: 1. Path resolution mismatch on Windows: init and auto_init_project used unresolved Path.cwd() but find_parent_with_marker/find_project_root resolve internally, causing comparison failures and daemon key mismatches. 2. LMDB not released on remove_project: The daemon ProjectRegistry dropped the Project from dicts without closing its SQLite connection or forcing GC of the Rust LMDB environment. On free-threaded Python (3.14t) and Windows, deferred GC kept the LMDB open, causing environment already open errors and PermissionErrors when deleting db files. 3. Silent connection close on streaming errors: When update_index async iteration failed in the daemon, the connection was closed without sending an ErrorResponse, causing the client to get an unhelpful EOFError. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…lter On 3.14t (free-threaded Python), gc.collect() alone does not release the Rust LMDB environment because deferred reference counting keeps core.Environment alive through App._core_env_app, ContextProvider._core_env, and Environment._core_env. Explicitly null these internal references in Project.close() before gc.collect() so the Rust object is freed promptly. Also resolve Path.cwd() in resolve_default_path() — on Windows, the unresolved cwd did not match the resolved project_root, causing relative_to() to fail and the subdirectory path filter to be skipped. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Revert fragile internal attribute clearing. On free-threaded Python, the first gc.collect() frees Python wrappers whose Rust Drop implementations issue further deferred Py_DECREF calls on core.Environment; a second gc.collect() flushes those and actually drops the LMDB handle. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
On 3.14t, deferred reference counting means the Rust LMDB environment is not released immediately after remove_project + gc.collect(). Add a 1-second sleep in the two tests that reset and re-index, giving the runtime time to process pending deferred Py_DECREF calls. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Instead of sleeping, restart the daemon after reset in the two tests that re-index after removing databases. This reliably releases the LMDB environment on all platforms including free-threaded Python (3.14t). Also increase _wait_for_daemon timeout from 5s to 10s — Windows CI runners occasionally need longer to start the daemon subprocess. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
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.
#52