Skip to content

Commit 7b15fd9

Browse files
simplify background tasks with SessionSnapshot (#289)
1 parent 209b113 commit 7b15fd9

File tree

2 files changed

+52
-7
lines changed

2 files changed

+52
-7
lines changed

crates/djls-server/src/server.rs

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ use crate::ext::TextDocumentIdentifierExt;
1919
use crate::ext::UriExt;
2020
use crate::queue::Queue;
2121
use crate::session::Session;
22+
use crate::session::SessionSnapshot;
2223

2324
const SERVER_NAME: &str = "Django Language Server";
2425
const SERVER_VERSION: &str = "0.1.0";
@@ -59,12 +60,15 @@ impl DjangoLanguageServer {
5960

6061
pub async fn with_session_task<F, Fut>(&self, f: F)
6162
where
62-
F: FnOnce(Arc<Mutex<Session>>) -> Fut + Send + 'static,
63+
F: FnOnce(SessionSnapshot) -> Fut + Send + 'static,
6364
Fut: Future<Output = anyhow::Result<()>> + Send + 'static,
6465
{
65-
let session_arc = Arc::clone(&self.session);
66+
let snapshot = {
67+
let session = self.session.lock().await;
68+
session.snapshot()
69+
};
6670

67-
if let Err(e) = self.queue.submit(async move { f(session_arc).await }).await {
71+
if let Err(e) = self.queue.submit(async move { f(snapshot).await }).await {
6872
tracing::error!("Failed to submit task: {}", e);
6973
} else {
7074
tracing::info!("Task submitted successfully");
@@ -174,10 +178,8 @@ impl LanguageServer for DjangoLanguageServer {
174178
async fn initialized(&self, _params: lsp_types::InitializedParams) {
175179
tracing::info!("Server received initialized notification.");
176180

177-
self.with_session_task(move |session_arc| async move {
178-
let session = session_arc.lock().await;
179-
180-
if let Some(project) = session.project() {
181+
self.with_session_task(move |session| async move {
182+
if let Some(project) = session.db().project() {
181183
let path = project.root(session.db()).clone();
182184
tracing::info!("Task: Starting initialization for project at: {}", path);
183185
project.initialize(session.db());

crates/djls-server/src/session.rs

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,10 @@ impl Session {
7171
}
7272
}
7373

74+
pub fn snapshot(&self) -> SessionSnapshot {
75+
SessionSnapshot::new(self.db.clone(), self.client_capabilities)
76+
}
77+
7478
pub fn client_capabilities(&self) -> ClientCapabilities {
7579
self.client_capabilities
7680
}
@@ -193,6 +197,30 @@ impl Default for Session {
193197
}
194198
}
195199

200+
/// Immutable snapshot of session state for background tasks
201+
#[derive(Clone)]
202+
pub struct SessionSnapshot {
203+
db: DjangoDatabase,
204+
client_capabilities: ClientCapabilities,
205+
}
206+
207+
impl SessionSnapshot {
208+
pub fn new(db: DjangoDatabase, client_capabilities: ClientCapabilities) -> Self {
209+
Self {
210+
db,
211+
client_capabilities,
212+
}
213+
}
214+
215+
pub fn db(&self) -> &DjangoDatabase {
216+
&self.db
217+
}
218+
219+
pub fn client_capabilities(&self) -> ClientCapabilities {
220+
self.client_capabilities
221+
}
222+
}
223+
196224
#[derive(Debug, Clone, Copy)]
197225
pub struct ClientCapabilities {
198226
pull_diagnostics: bool,
@@ -334,6 +362,21 @@ mod tests {
334362
assert_eq!(content, "updated");
335363
}
336364

365+
#[test]
366+
fn test_snapshot_creation() {
367+
let session = Session::default();
368+
let snapshot = session.snapshot();
369+
370+
assert_eq!(
371+
session.client_capabilities().position_encoding(),
372+
snapshot.client_capabilities().position_encoding()
373+
);
374+
assert_eq!(
375+
session.project().is_some(),
376+
snapshot.db().project().is_some()
377+
);
378+
}
379+
337380
#[test]
338381
fn test_negotiate_prefers_utf8_when_available() {
339382
let capabilities = lsp_types::ClientCapabilities {

0 commit comments

Comments
 (0)