Fix thread-unsafe _workspace_path_override race (#43)#54
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (2)
🚧 Files skipped from review as they are similar to previous changes (2)
📝 WalkthroughWalkthroughThis PR fixes thread-safety of the global workspace path override in ChangesWorkspace Path Thread Safety
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@tests/test_workspace_path_thread_safety.py`:
- Around line 63-75: The test performs two separate reads
(get_workspace_path_override() then resolve_workspace_path()) and compares them
as if atomic, which makes the assertion flaky under concurrent writers; change
the assertion to use a single-observation target by either (a) only asserting
that resolve_workspace_path() is one of the allowed resolved realpaths (e.g.,
os.path.realpath(self.path_a) or os.path.realpath(self.path_b)), or (b)
introduce/use a helper that returns both override and resolved under the same
lock and assert their relationship from that single snapshot; update the checks
around get_workspace_path_override and resolve_workspace_path in
tests/test_workspace_path_thread_safety.py (and similarly at the other
occurrence) to follow one of these approaches.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 915eb314-e9e6-4ddf-ab36-785cf938429d
📒 Files selected for processing (2)
tests/test_workspace_path_thread_safety.pyutils/workspace_path.py
Summary
Fixes #43 by serializing access to the module-level
_workspace_path_overridewith athreading.Lock. The override is written byPOST /api/set-workspace(and--base-dir) and read on every call toresolve_workspace_path(); without synchronization, threaded WSGI deployments (gunicorn--threads, waitress, etc.) can race and serve data from the wrong workspace path._workspace_path_lockand document the locking contract on_workspace_path_overrideget_workspace_path_override()andresolve_workspace_path()(snapshot under lock, then expand outside)set_workspace_path_override(); widen type tostr | Nonefor test/cleanup clearstests/test_workspace_path_thread_safety.pywith concurrent set/resolve and clear/set/resolve stress testsEval reference:
workspace-path-race-conditioncluster (test 13) in the April 2026 Python eval baseline.Why a lock (not Flask
g/session)The override is server-wide configuration for this localhost tool, not per-request state. A lock is the minimum change that makes threaded deployment safe without changing API semantics. Per-user isolation would require session-scoped storage and is out of scope for this fix.
Test plan
python -m unittest tests.test_workspace_path_thread_safety -vpython -m unittest tests.test_workspace_path_validation -v(existing set-workspace regressions still pass)POST /api/set-workspacewhile hitting list/search endpoints concurrently; confirm stable workspace selectionSummary by CodeRabbit
Bug Fixes
Tests