fix: scope CodebaseGraphManager to current repo for concurrent sessions (alternative approach)#538
Merged
scottfrasso merged 1 commit intoshotgun-sh:mainfrom Apr 14, 2026
Conversation
Adds a process-wide class variable _scope_graph_ids to
CodebaseGraphManager, set once at startup from the CWD. A single
_iter_databases() helper replaces every .glob("*.kuzu") call, so all
existing and future enumeration methods automatically respect the scope.
Root cause: detect_database_issues(), list_graphs(), and
cleanup_corrupted_databases() all globbed every .kuzu file in
~/.shotgun-sh/codebases/. When another Shotgun session was running on
a different repo, its database was exclusively locked by Kuzu. The
health check reported this as an issue, showing a blocking "database
locked" dialog — even though the current repo's database was fine.
Changes:
- manager.py: add _scope_graph_ids ClassVar (default None) and
_iter_databases() method. Replace 3 glob sites with _iter_databases().
- main.py: set _scope_graph_ids = [generate_graph_id(cwd)] once in
main() before any subcommand runs. Covers TUI, shotgun run, and all
other CLI commands in a single place.
- cli/codebase/commands.py: unset scope in list_codebases() — the one
command that legitimately needs to enumerate all indexed databases.
This approach is ~15 lines of meaningful change across 3 files with
zero parameter passing. Any future method that enumerates databases
uses _iter_databases() and automatically inherits the scope.
Alternative approach: PR shotgun-sh#535 patches each method individually using
optional graph_ids parameters and .meta.json sidecar files.
Tested with real_ladybug==0.15.1 against 3 simulated repos under real
Kuzu file locks (multiprocessing). All 8 tests pass:
T1: bug reproduced (OLD globs all, 2 locked, blocks 3rd session)
T2: fix validates (NEW scope, alpha/beta never opened)
T3: list_graphs scoped (opens 1/3 not 3/3)
T4: each CWD yields correct scope isolation
T5: unrelated CWD returns empty
T6: scoped cleanup avoids locked peers
T7: backward compat (scope=None full scan still works)
T8: graph_id uniqueness across 3 repos
Closes shotgun-sh#534
Made-with: Cursor
Contributor
Author
|
Hey team! I hd a bit more time to think about the problem today and above is a cleaner fix approach. |
2 tasks
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
When two Shotgun sessions run simultaneously on different repositories in the same parent directory, a startup health check scans every
.kuzufile in~/.shotgun-sh/codebases/. Kuzu uses exclusive file locks, so any database held open by a peer session is reported as "locked" — even though the current repo's database is perfectly fine. This shows a blocking dialog and prevents the second session from starting.Reported in #534.
Root cause
Three methods in
CodebaseGraphManagerglob the entire storage directory:detect_database_issues()— the startup health checklist_graphs()— used byshotgun codebase listand graph servicecleanup_corrupted_databases()— called during startup and recoveryThis fix (alternative to #535)
Add a single process-wide class variable
_scope_graph_idstoCodebaseGraphManager, set once at process startup from the current working directory. A new_iter_databases()method replaces all three.glob("*.kuzu")calls. Any future method that enumerates databases uses_iter_databases()and automatically inherits the scope — no parameter threading required.Total: 3 files changed, 43 insertions(+), 9 deletions(-)
Comparison with PR #535
graph_idsparameter on each method +.meta.jsonsidecarsClassVar, set once inmain.py_iter_databases()handles it automaticallyshotgun codebase listHow it works
Every Shotgun process starts from a CWD.
main.pycallsgenerate_graph_id(os.getcwd())and stores the result in the class variable. Because_scope_graph_idsis aClassVar, every instance ofCodebaseGraphManagercreated anywhere in the process automatically respects the scope — TUI,shotgun run,shotgun codebase index, benchmarks, all covered by the two lines inmain.py.The only exception is
shotgun codebase list, which legitimately needs to show all indexed repositories. It clears the scope before querying.Tests
Standalone test script using
real_ladybug==0.15.1andmultiprocessingto hold real Kuzu file locks. 3 simulated repos (project-alpha,project-beta,project-gamma). All 8 tests pass:list_graphsscoped: opens 1/3 not 3/3scope=Nonestill full-scansgraph_iduniqueness across 3 reposCloses #534
Made with Cursor