Integrate Salsa into document tracking for server (#148)
Some checks are pending
lint / rustfmt (push) Waiting to run
lint / clippy (push) Waiting to run
lint / cargo-check (push) Waiting to run
lint / pre-commit (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
test / Python , Django () (push) Blocked by required conditions
test / tests (push) Blocked by required conditions
zizmor 🌈 / zizmor latest via PyPI (push) Waiting to run

This commit is contained in:
Josh Thomas 2025-05-15 01:35:49 -05:00 committed by GitHub
parent d677aacf7c
commit c29b268326
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 261 additions and 142 deletions

View file

@ -1,15 +1,43 @@
use djls_conf::Settings;
use djls_project::DjangoProject;
use salsa::StorageHandle;
use tower_lsp_server::lsp_types::ClientCapabilities;
use crate::db::ServerDatabase;
use crate::documents::Store;
#[derive(Debug, Default)]
#[derive(Default)]
pub struct Session {
client_capabilities: Option<ClientCapabilities>,
project: Option<DjangoProject>,
documents: Store,
settings: Settings,
/// A thread-safe Salsa database handle that can be shared between threads.
///
/// This implements the insight from [this Salsa Zulip discussion](https://salsa.zulipchat.com/#narrow/channel/145099-Using-Salsa/topic/.E2.9C.94.20Advice.20on.20using.20salsa.20from.20Sync.20.2B.20Send.20context/with/495497515)
/// where we're using the `StorageHandle` to create a thread-safe handle that can be
/// shared between threads. When we need to use it, we clone the handle to get a new reference.
///
/// Usage:
/// ```rust,ignore
/// // Use the StorageHandle in Session
/// let db_handle = StorageHandle::new(None);
///
/// // Clone it to pass to different threads
/// let db_handle_clone = db_handle.clone();
///
/// // Use it in an async context
/// async_fn(move || {
/// // Get a database from the handle
/// let storage = db_handle_clone.into_storage();
/// let db = ServerDatabase::new(storage);
///
/// // Use the database
/// db.some_query(args)
/// });
/// ```
db_handle: StorageHandle<ServerDatabase>,
}
impl Session {
@ -19,11 +47,12 @@ impl Session {
project: None,
documents: Store::new(),
settings: Settings::default(),
db_handle: StorageHandle::new(None),
}
}
pub fn client_capabilities(&self) -> &Option<ClientCapabilities> {
&self.client_capabilities
pub fn client_capabilities(&self) -> Option<&ClientCapabilities> {
self.client_capabilities.as_ref()
}
pub fn client_capabilities_mut(&mut self) -> &mut Option<ClientCapabilities> {
@ -53,4 +82,21 @@ impl Session {
pub fn settings_mut(&mut self) -> &mut Settings {
&mut self.settings
}
/// Get the raw database handle from the session
///
/// Note: In most cases, you'll want to use `db()` instead to get a usable
/// database instance directly.
pub fn db_handle(&self) -> &StorageHandle<ServerDatabase> {
&self.db_handle
}
/// Get a database instance directly from the session
///
/// This creates a usable database from the handle, which can be used
/// to query and update data in the database.
pub fn db(&self) -> ServerDatabase {
let storage = self.db_handle.clone().into_storage();
ServerDatabase::new(storage)
}
}