Start work on deserializing Workspace

This commit is contained in:
Anthony Eid
2024-08-03 13:42:01 -04:00
parent 8b63c1ab6f
commit d4904f97bb
6 changed files with 101 additions and 54 deletions

1
Cargo.lock generated
View File

@@ -8035,6 +8035,7 @@ dependencies = [
"language",
"log",
"lsp",
"multi_buffer",
"node_runtime",
"parking_lot",
"pathdiff",

View File

@@ -72,6 +72,7 @@ text.workspace = true
util.workspace = true
unicase.workspace = true
which.workspace = true
multi_buffer.workspace = true
[dev-dependencies]
client = { workspace = true, features = ["test-support"] }

View File

@@ -142,6 +142,8 @@ pub use worktree::{
FS_WATCH_LATENCY,
};
pub use multi_buffer::MultiBuffer;
const MAX_SERVER_REINSTALL_ATTEMPT_COUNT: u64 = 4;
const SERVER_REINSTALL_DEBOUNCE_TIMEOUT: Duration = Duration::from_secs(1);
const SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT: Duration = Duration::from_secs(5);
@@ -183,7 +185,7 @@ pub struct Project {
language_server_ids: HashMap<(WorktreeId, LanguageServerName), LanguageServerId>,
debug_adapters: HashMap<DebugAdapterClientId, DebugAdapterClientState>,
pub open_breakpoints: Arc<RwLock<BTreeMap<BufferId, HashSet<Breakpoint>>>>,
closed_breakpoints: Option<Arc<RwLock<BTreeMap<ProjectPath, Vec<u64>>>>>,
pub closed_breakpoints: Arc<RwLock<BTreeMap<ProjectPath, Vec<u64>>>>,
language_server_statuses: BTreeMap<LanguageServerId, LanguageServerStatus>,
last_formatting_failure: Option<String>,
last_workspace_edits_by_language_server: HashMap<LanguageServerId, ProjectTransaction>,
@@ -1312,15 +1314,13 @@ impl Project {
))
}
pub fn serialize_breakpoints(&self, cx: &ModelContext<Self>) -> Vec<(PathBuf, Vec<u64>)> {
pub fn serialize_breakpoints(&self, cx: &ModelContext<Self>) -> HashMap<PathBuf, Vec<u64>> {
let breakpoint_read_guard = self.open_breakpoints.read();
let mut result = Vec::new();
let mut result: HashMap<PathBuf, Vec<u64>> = Default::default();
for buffer_id in breakpoint_read_guard.keys() {
if let Some(serialize_breakpoints) =
self.serialize_breakpoint_for_buffer_id(&buffer_id, cx)
{
result.push(serialize_breakpoints)
if let Some((key, value)) = self.serialize_breakpoint_for_buffer_id(&buffer_id, cx) {
result.insert(key, value);
}
}
@@ -2222,12 +2222,37 @@ impl Project {
cx: &mut ModelContext<Self>,
) -> Task<Result<(Option<ProjectEntryId>, AnyModel)>> {
let task = self.open_buffer(path.clone(), cx);
cx.spawn(move |_, cx| async move {
cx.spawn(move |project, mut cx| async move {
let buffer = task.await?;
let project_entry_id = buffer.read_with(&cx, |buffer, cx| {
File::from_dyn(buffer.file()).and_then(|file| file.project_entry_id(cx))
let (project_entry_id, buffer_id) = buffer.read_with(&cx, |buffer, cx| {
(
File::from_dyn(buffer.file()).and_then(|file| file.project_entry_id(cx)),
buffer.remote_id(),
)
})?;
let multi_buffer = cx.new_model(|cx| MultiBuffer::singleton(buffer.clone(), cx))?;
dbg!("Opening a path", path.path.clone());
project.update(&mut cx, |project, cx| {
let breakpoint_rows = { project.closed_breakpoints.write().remove(&path) };
dbg!(&project.closed_breakpoints.read());
let snapshot = multi_buffer.read(cx).snapshot(cx);
dbg!(&breakpoint_rows);
if let Some(breakpoint_row) = breakpoint_rows {
let mut write_guard = project.open_breakpoints.write();
let buffer_breakpoints = write_guard.entry(buffer_id).or_default();
dbg!(&buffer_breakpoints);
for row in breakpoint_row {
let position = snapshot.anchor_at(Point::new(row as u32, 0), Bias::Left);
buffer_breakpoints.insert(Breakpoint { position });
}
}
})?;
dbg!("Path open successfully");
let buffer: &AnyModel = &buffer;
Ok((project_entry_id, buffer.clone()))
})

View File

@@ -499,7 +499,7 @@ impl WorkspaceDb {
})
.and_then(|mut prepared_statement| (prepared_statement)(workspace_id));
let breakpoints: Option<Vec<(PathBuf, Vec<u64>)>> = match breakpoints {
let breakpoints: HashMap<PathBuf, Vec<u64>> = match breakpoints {
Ok(bp) => {
if bp.is_empty() {
log::error!("Breakpoints are empty");
@@ -511,15 +511,11 @@ impl WorkspaceDb {
map.entry(file_path).or_default().push(breakpoint.position);
}
Some(
map.into_iter()
.map(|(file_path, breakpoints)| (file_path, breakpoints))
.collect(),
)
map
}
Err(msg) => {
log::error!("{msg}");
None
Default::default()
}
};
@@ -654,7 +650,7 @@ impl WorkspaceDb {
display,
docks,
session_id: None,
breakpoints: None,
breakpoints: Default::default(),
})
}
@@ -669,39 +665,39 @@ impl WorkspaceDb {
DELETE FROM panes WHERE workspace_id = ?1;))?(workspace.id)
.context("Clearing old panes")?;
if let Some(breakpoints) = workspace.breakpoints {
for (file_path, rows) in breakpoints {
let path = file_path.as_path();
for (file_path, rows) in workspace.breakpoints {
let path = file_path.as_path();
match conn.exec_bound(sql!(
DELETE FROM breakpoints
WHERE workspace_id = ?1 AND file_path = ?2;))?((workspace.id, path)) {
Err(err) => {
log::error!("{err}");
// continue;
}
Ok(_) => {}
}
for row in rows {
match conn.exec_bound(sql!(
DELETE FROM breakpoints
WHERE workspace_id = ?1 AND file_path = ?2;))?((workspace.id, path)) {
INSERT INTO breakpoints (workspace_id, file_path, breakpoint_location)
VALUES (?1, ?2, ?3);))?
((
workspace.id,
path,
Breakpoint { position: row },
)) {
Err(err) => {
log::error!("{err}");
// continue;
continue;
}
Ok(_) => {}
}
for row in rows {
match conn.exec_bound(sql!(
INSERT INTO breakpoints (workspace_id, file_path, breakpoint_location)
VALUES (?1, ?2, ?3);))?
((
workspace.id,
path,
Breakpoint { position: row },
)) {
Err(err) => {
log::error!("{err}");
continue;
}
Ok(_) => {}
}
}
}
}
match workspace.location {
SerializedWorkspaceLocation::Local(local_paths, local_paths_order) => {
conn.exec_bound(sql!(
@@ -1278,7 +1274,7 @@ mod tests {
docks: Default::default(),
centered_layout: false,
session_id: None,
breakpoints: None,
breakpoints: Default::deafult(),
};
let workspace_2 = SerializedWorkspace {
@@ -1290,7 +1286,7 @@ mod tests {
docks: Default::default(),
centered_layout: false,
session_id: None,
breakpoints: None,
breakpoints: Default::deafult(),
};
db.save_workspace(workspace_1.clone()).await;
@@ -1394,7 +1390,7 @@ mod tests {
docks: Default::default(),
centered_layout: false,
session_id: None,
breakpoints: None,
breakpoints: Default::deafult(),
};
db.save_workspace(workspace.clone()).await;
@@ -1428,7 +1424,7 @@ mod tests {
docks: Default::default(),
centered_layout: false,
session_id: None,
breakpoints: None,
breakpoints: Default::deafult(),
};
let mut workspace_2 = SerializedWorkspace {
@@ -1440,7 +1436,7 @@ mod tests {
docks: Default::default(),
centered_layout: false,
session_id: None,
breakpoints: None,
breakpoints: Default::deafult(),
};
db.save_workspace(workspace_1.clone()).await;
@@ -1482,7 +1478,7 @@ mod tests {
docks: Default::default(),
centered_layout: false,
session_id: None,
breakpoints: None,
breakpoints: Default::deafult(),
};
db.save_workspace(workspace_3.clone()).await;
@@ -1518,7 +1514,7 @@ mod tests {
docks: Default::default(),
centered_layout: false,
session_id: Some("session-id-1".to_owned()),
breakpoints: None,
breakpoints: Default::deafult(),
};
let workspace_2 = SerializedWorkspace {
@@ -1530,7 +1526,7 @@ mod tests {
docks: Default::default(),
centered_layout: false,
session_id: Some("session-id-1".to_owned()),
breakpoints: None,
breakpoints: Default::deafult(),
};
let workspace_3 = SerializedWorkspace {
@@ -1542,7 +1538,7 @@ mod tests {
docks: Default::default(),
centered_layout: false,
session_id: Some("session-id-2".to_owned()),
breakpoints: None,
breakpoints: Default::deafult(),
};
let workspace_4 = SerializedWorkspace {
@@ -1554,7 +1550,7 @@ mod tests {
docks: Default::default(),
centered_layout: false,
session_id: None,
breakpoints: None,
breakpoints: Default::deafult(),
};
db.save_workspace(workspace_1.clone()).await;
@@ -1592,7 +1588,7 @@ mod tests {
docks: Default::default(),
centered_layout: false,
session_id: None,
breakpoints: None,
breakpoints: Default::deafult(),
}
}

View File

@@ -5,6 +5,7 @@ use crate::{
use anyhow::{Context, Result};
use async_recursion::async_recursion;
use client::DevServerProjectId;
use collections::HashMap;
use db::sqlez::{
bindable::{Bind, Column, StaticColumnCount},
statement::Statement,
@@ -216,7 +217,7 @@ pub(crate) struct SerializedWorkspace {
pub(crate) display: Option<Uuid>,
pub(crate) docks: DockStructure,
pub(crate) session_id: Option<String>,
pub(crate) breakpoints: Option<Vec<(PathBuf, Vec<u64>)>>,
pub(crate) breakpoints: HashMap<PathBuf, Vec<u64>>,
}
#[derive(Debug, PartialEq, Clone, Default)]

View File

@@ -1089,6 +1089,7 @@ impl Workspace {
let mut worktree_roots: HashSet<Arc<Path>> = Default::default();
let mut project_paths: Vec<(PathBuf, Option<ProjectPath>)> =
Vec::with_capacity(paths_to_open.len());
for path in paths_to_open.into_iter() {
if let Some((worktree, project_entry)) = cx
.update(|cx| {
@@ -4035,7 +4036,7 @@ impl Workspace {
docks,
centered_layout: self.centered_layout,
session_id: self.session_id.clone(),
breakpoints: Some(breakpoint_lines),
breakpoints: breakpoint_lines,
};
return cx.spawn(|_| persistence::DB.save_workspace(serialized_workspace));
}
@@ -4100,6 +4101,8 @@ impl Workspace {
let mut center_items = None;
// Traverse the splits tree and add to things
// Add unopened breakpoints to project before opening any
// buffer
if let Some((group, active_pane, items)) = serialized_workspace
.center_group
.deserialize(
@@ -4133,6 +4136,26 @@ impl Workspace {
}
})?;
dbg!(&serialized_workspace.breakpoints);
workspace.update(&mut cx, |workspace, cx| {
workspace.project().update(cx, |project, _cx| {
let mut write_guard = project.closed_breakpoints.write();
for project_path in items_by_project_path.keys() {
write_guard.insert(
project_path.clone(),
serialized_workspace
.breakpoints
.get(&project_path.path.to_path_buf())
.unwrap_or(&vec![1])
.clone(),
);
}
dbg!(&write_guard);
})
})?;
let opened_items = paths_to_open
.into_iter()
.map(|path_to_open| {