mirror of
https://github.com/joshuadavidthomas/django-language-server.git
synced 2025-09-04 01:10:42 +00:00
remove
This commit is contained in:
parent
84f1073a1d
commit
43138a9dd3
1 changed files with 0 additions and 94 deletions
|
@ -1,94 +0,0 @@
|
|||
# OUTDATED - See ARCHITECTURE_INSIGHTS.md for current solution
|
||||
|
||||
## This document is preserved for historical context but is OUTDATED
|
||||
## We found the StorageHandle solution that solves the Send+Sync issue
|
||||
|
||||
# Key Findings from Ruff's Architecture
|
||||
|
||||
Based on the exploration, here's what we discovered:
|
||||
|
||||
## Current Django LS Architecture
|
||||
|
||||
### What We Have:
|
||||
1. `Database` struct with `#[derive(Clone)]` and Salsa storage
|
||||
2. `WorkspaceDatabase` that wraps `Database` and uses `DashMap` for thread-safe file storage
|
||||
3. `Session` that owns `WorkspaceDatabase` directly (not wrapped in Arc<Mutex>)
|
||||
4. Tower-LSP server that requires `Send + Sync` for async handlers
|
||||
|
||||
### The Problem:
|
||||
- `Database` is not `Sync` due to `RefCell<QueryStack>` and `UnsafeCell<HashMap>` in Salsa's `ZalsaLocal`
|
||||
- This prevents `Session` from being `Sync`, which breaks tower-lsp async handlers
|
||||
|
||||
## Ruff's Solution (From Analysis)
|
||||
|
||||
### They Don't Make Database Sync!
|
||||
The key insight is that Ruff **doesn't actually make the database Send + Sync**. Instead:
|
||||
|
||||
1. **Clone for Background Work**: They clone the database for each background task
|
||||
2. **Move Not Share**: The cloned database is *moved* into the task (requires Send, not Sync)
|
||||
3. **Message Passing**: Results are sent back via channels
|
||||
|
||||
### Critical Difference:
|
||||
- Ruff uses a custom LSP implementation that doesn't require `Sync` on the session
|
||||
- Tower-LSP *does* require `Sync` because handlers take `&self`
|
||||
|
||||
## The Real Problem
|
||||
|
||||
Tower-LSP's `LanguageServer` trait requires:
|
||||
```rust
|
||||
async fn initialize(&self, ...) -> ...
|
||||
// ^^^^^ This requires self to be Sync!
|
||||
```
|
||||
|
||||
But with Salsa's current implementation, the Database can never be Sync.
|
||||
|
||||
## Solution Options
|
||||
|
||||
### Option 1: Wrap Database in Arc<Mutex> (Current Workaround)
|
||||
```rust
|
||||
pub struct Session {
|
||||
database: Arc<Mutex<WorkspaceDatabase>>,
|
||||
// ...
|
||||
}
|
||||
```
|
||||
Downsides: Lock contention, defeats purpose of Salsa's internal optimization
|
||||
|
||||
### Option 2: Move Database Out of Session
|
||||
```rust
|
||||
pub struct Session {
|
||||
// Don't store database here
|
||||
file_index: Arc<DashMap<Url, FileContent>>,
|
||||
settings: Settings,
|
||||
}
|
||||
|
||||
// Create database on demand for each request
|
||||
impl LanguageServer for Server {
|
||||
async fn some_handler(&self) {
|
||||
let db = create_database_from_index(&self.session.file_index);
|
||||
// Use db for this request
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Option 3: Use Actor Pattern
|
||||
```rust
|
||||
pub struct DatabaseActor {
|
||||
database: WorkspaceDatabase,
|
||||
rx: mpsc::Receiver<DatabaseCommand>,
|
||||
}
|
||||
|
||||
pub struct Session {
|
||||
db_tx: mpsc::Sender<DatabaseCommand>,
|
||||
}
|
||||
```
|
||||
|
||||
### Option 4: Custom unsafe Send/Sync implementation
|
||||
This is risky but possible if we ensure single-threaded access patterns.
|
||||
|
||||
## The Salsa Version Mystery
|
||||
|
||||
We're using the exact same Salsa commit as Ruff, with the same features. The issue is NOT the Salsa version, but how tower-lsp forces us to use it.
|
||||
|
||||
Ruff likely either:
|
||||
1. Doesn't use tower-lsp (has custom implementation)
|
||||
2. Or structures their server differently to avoid needing Sync on the database
|
Loading…
Add table
Add a link
Reference in a new issue