Description
Once #104 (split NotificationCache) and #108 (split lock from LSP round-trip) land, the remaining
Translator state held under lock will be almost entirely read-only during tool calls. At that point
replacing Arc<Mutex<Translator>> with Arc<RwLock<Translator>> will allow concurrent read
operations (hover, definition, references, etc.) to run in parallel without contention.
Issue #108 explicitly defers this — "No RwLock (all handlers need exclusive access until
this split is complete)" — making this the natural Phase 3 of the concurrency improvement arc.
Problem
After #108 lands, each tool handler will:
- Acquire exclusive write access only for the short
ensure_open prepare phase (~2 ms)
- Release the lock before the LSP round-trip
At that point, using Mutex still prevents concurrent reads of the Translator config fields
(lsp_clients, workspace_roots, extension_map), which are all read-only after serve().
Expected Behavior
Read-only tool handlers (hover, definition, references, document_symbols, completions,
call_hierarchy, workspace_symbol_search, code_actions) acquire a read lock and run concurrently.
Mutating handlers (rename_symbol, format_document) acquire a write lock.
Actual Behavior
All handlers acquire an exclusive Mutex lock, serialising even concurrent read-only calls.
Implementation Sketch
- Change
Arc<Mutex<Translator>> to Arc<RwLock<Translator>> in mcp/server.rs and mcp/handlers.rs
- Update read-only handlers:
translator.read().await
- Update mutating handlers:
translator.write().await
- Verify no lock held across
.await in read path
Blocked By
#104, #108
Spec
.local/specs/001-rwlock-translator/spec.md
Environment
- Version: 0.3.6
- Branch: fix/translator-lock-starvation
Description
Once #104 (split NotificationCache) and #108 (split lock from LSP round-trip) land, the remaining
Translator state held under lock will be almost entirely read-only during tool calls. At that point
replacing
Arc<Mutex<Translator>>withArc<RwLock<Translator>>will allow concurrent readoperations (hover, definition, references, etc.) to run in parallel without contention.
Issue #108 explicitly defers this — "No RwLock (all handlers need exclusive access until
this split is complete)" — making this the natural Phase 3 of the concurrency improvement arc.
Problem
After #108 lands, each tool handler will:
ensure_openprepare phase (~2 ms)At that point, using
Mutexstill prevents concurrent reads of theTranslatorconfig fields(
lsp_clients,workspace_roots,extension_map), which are all read-only afterserve().Expected Behavior
Read-only tool handlers (hover, definition, references, document_symbols, completions,
call_hierarchy, workspace_symbol_search, code_actions) acquire a read lock and run concurrently.
Mutating handlers (rename_symbol, format_document) acquire a write lock.
Actual Behavior
All handlers acquire an exclusive Mutex lock, serialising even concurrent read-only calls.
Implementation Sketch
Arc<Mutex<Translator>>toArc<RwLock<Translator>>inmcp/server.rsandmcp/handlers.rstranslator.read().awaittranslator.write().await.awaitin read pathBlocked By
#104, #108
Spec
.local/specs/001-rwlock-translator/spec.md
Environment