mirror of
https://github.com/joshuadavidthomas/django-language-server.git
synced 2025-09-10 20:36:21 +00:00
simplify salsa db management with Clone
+ Arc<Mutex<Session>>
(#194)
Some checks are pending
test / Python , Django () (push) Blocked by required conditions
test / tests (push) Blocked by required conditions
zizmor 🌈 / zizmor latest via PyPI (push) Waiting to run
lint / pre-commit (push) Waiting to run
lint / rustfmt (push) Waiting to run
lint / clippy (push) Waiting to run
lint / cargo-check (push) Waiting to run
release / build (push) Waiting to run
release / test (push) Waiting to run
release / release (push) Blocked by required conditions
test / generate-matrix (push) Waiting to run
Some checks are pending
test / Python , Django () (push) Blocked by required conditions
test / tests (push) Blocked by required conditions
zizmor 🌈 / zizmor latest via PyPI (push) Waiting to run
lint / pre-commit (push) Waiting to run
lint / rustfmt (push) Waiting to run
lint / clippy (push) Waiting to run
lint / cargo-check (push) Waiting to run
release / build (push) Waiting to run
release / test (push) Waiting to run
release / release (push) Blocked by required conditions
test / generate-matrix (push) Waiting to run
This commit is contained in:
parent
b90862d72a
commit
67c5574f37
6 changed files with 46 additions and 477 deletions
|
@ -3,7 +3,7 @@ use std::sync::Arc;
|
|||
|
||||
use djls_workspace::paths;
|
||||
use djls_workspace::FileKind;
|
||||
use tokio::sync::RwLock;
|
||||
use tokio::sync::Mutex;
|
||||
use tower_lsp_server::jsonrpc::Result as LspResult;
|
||||
use tower_lsp_server::lsp_types;
|
||||
use tower_lsp_server::Client;
|
||||
|
@ -19,7 +19,7 @@ const SERVER_VERSION: &str = "0.1.0";
|
|||
pub struct DjangoLanguageServer {
|
||||
#[allow(dead_code)] // will be needed when diagnostics and other features are added
|
||||
client: Client,
|
||||
session: Arc<RwLock<Option<Session>>>,
|
||||
session: Arc<Mutex<Session>>,
|
||||
queue: Queue,
|
||||
_log_guard: WorkerGuard,
|
||||
}
|
||||
|
@ -29,7 +29,7 @@ impl DjangoLanguageServer {
|
|||
pub fn new(client: Client, log_guard: WorkerGuard) -> Self {
|
||||
Self {
|
||||
client,
|
||||
session: Arc::new(RwLock::new(None)),
|
||||
session: Arc::new(Mutex::new(Session::default())),
|
||||
queue: Queue::new(),
|
||||
_log_guard: log_guard,
|
||||
}
|
||||
|
@ -38,34 +38,22 @@ impl DjangoLanguageServer {
|
|||
pub async fn with_session<F, R>(&self, f: F) -> R
|
||||
where
|
||||
F: FnOnce(&Session) -> R,
|
||||
R: Default,
|
||||
{
|
||||
let session = self.session.read().await;
|
||||
if let Some(s) = &*session {
|
||||
f(s)
|
||||
} else {
|
||||
tracing::error!("Attempted to access session before initialization");
|
||||
R::default()
|
||||
}
|
||||
let session = self.session.lock().await;
|
||||
f(&session)
|
||||
}
|
||||
|
||||
pub async fn with_session_mut<F, R>(&self, f: F) -> R
|
||||
where
|
||||
F: FnOnce(&mut Session) -> R,
|
||||
R: Default,
|
||||
{
|
||||
let mut session = self.session.write().await;
|
||||
if let Some(s) = &mut *session {
|
||||
f(s)
|
||||
} else {
|
||||
tracing::error!("Attempted to access session before initialization");
|
||||
R::default()
|
||||
}
|
||||
let mut session = self.session.lock().await;
|
||||
f(&mut session)
|
||||
}
|
||||
|
||||
pub async fn with_session_task<F, Fut>(&self, f: F)
|
||||
where
|
||||
F: FnOnce(Arc<RwLock<Option<Session>>>) -> Fut + Send + 'static,
|
||||
F: FnOnce(Arc<Mutex<Session>>) -> Fut + Send + 'static,
|
||||
Fut: Future<Output = anyhow::Result<()>> + Send + 'static,
|
||||
{
|
||||
let session_arc = Arc::clone(&self.session);
|
||||
|
@ -89,8 +77,8 @@ impl LanguageServer for DjangoLanguageServer {
|
|||
let encoding = session.position_encoding();
|
||||
|
||||
{
|
||||
let mut session_lock = self.session.write().await;
|
||||
*session_lock = Some(session);
|
||||
let mut session_lock = self.session.lock().await;
|
||||
*session_lock = session;
|
||||
}
|
||||
|
||||
Ok(lsp_types::InitializeResult {
|
||||
|
@ -137,19 +125,16 @@ impl LanguageServer for DjangoLanguageServer {
|
|||
|
||||
self.with_session_task(move |session_arc| async move {
|
||||
let project_path_and_venv = {
|
||||
let session_lock = session_arc.read().await;
|
||||
match &*session_lock {
|
||||
Some(session) => session.project().map(|p| {
|
||||
(
|
||||
p.path().display().to_string(),
|
||||
session
|
||||
.settings()
|
||||
.venv_path()
|
||||
.map(std::string::ToString::to_string),
|
||||
)
|
||||
}),
|
||||
None => None,
|
||||
}
|
||||
let session_lock = session_arc.lock().await;
|
||||
session_lock.project().map(|p| {
|
||||
(
|
||||
p.path().display().to_string(),
|
||||
session_lock
|
||||
.settings()
|
||||
.venv_path()
|
||||
.map(std::string::ToString::to_string),
|
||||
)
|
||||
})
|
||||
};
|
||||
|
||||
if let Some((path_display, venv_path)) = project_path_and_venv {
|
||||
|
@ -163,17 +148,12 @@ impl LanguageServer for DjangoLanguageServer {
|
|||
}
|
||||
|
||||
let init_result = {
|
||||
let mut session_lock = session_arc.write().await;
|
||||
match &mut *session_lock {
|
||||
Some(session) => {
|
||||
if let Some(project) = session.project_mut().as_mut() {
|
||||
project.initialize(venv_path.as_deref())
|
||||
} else {
|
||||
// Project was removed between read and write locks
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
None => Ok(()),
|
||||
let mut session_lock = session_arc.lock().await;
|
||||
if let Some(project) = session_lock.project_mut().as_mut() {
|
||||
project.initialize(venv_path.as_deref())
|
||||
} else {
|
||||
// Project was removed between read and write locks
|
||||
Ok(())
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -189,10 +169,8 @@ impl LanguageServer for DjangoLanguageServer {
|
|||
);
|
||||
|
||||
// Clear project on error
|
||||
let mut session_lock = session_arc.write().await;
|
||||
if let Some(session) = &mut *session_lock {
|
||||
*session.project_mut() = None;
|
||||
}
|
||||
let mut session_lock = session_arc.lock().await;
|
||||
*session_lock.project_mut() = None;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -20,8 +20,8 @@ use url::Url;
|
|||
/// - Workspace operations (delegated to the Workspace facade)
|
||||
///
|
||||
/// All document lifecycle and database operations are delegated to the
|
||||
/// encapsulated Workspace, which provides thread-safe Salsa database
|
||||
/// management with proper mutation safety through `StorageHandleGuard`.
|
||||
/// encapsulated Workspace, which provides Salsa database management
|
||||
/// using the built-in Clone pattern for thread safety.
|
||||
pub struct Session {
|
||||
/// The Django project configuration
|
||||
project: Option<DjangoProject>,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue