Reduce amount of foreground tasks spawned on multibuffer/editor updates (#41479)
When doing a project wide search in zed on windows for `hang`, zed starts to freeze for a couple seconds ultimately starting to error with `Not enough quota is available to process this command.` when dispatching windows messages. The cause for this is that we simply overload the windows message pump due to the sheer amount of foreground tasks we spawn when we populate the project search. This PR is an attempt at reducing this. Release Notes: - Reduced hangs and stutters in large project file searches
This commit is contained in:
@@ -619,29 +619,24 @@ impl LocalBufferStore {
|
||||
worktree: Entity<Worktree>,
|
||||
cx: &mut Context<BufferStore>,
|
||||
) -> Task<Result<Entity<Buffer>>> {
|
||||
let load_buffer = worktree.update(cx, |worktree, cx| {
|
||||
let load_file = worktree.load_file(path.as_ref(), cx);
|
||||
let reservation = cx.reserve_entity();
|
||||
let buffer_id = BufferId::from(reservation.entity_id().as_non_zero_u64());
|
||||
let path = path.clone();
|
||||
cx.spawn(async move |_, cx| {
|
||||
let loaded = load_file.await.with_context(|| {
|
||||
format!("Could not open path: {}", path.display(PathStyle::local()))
|
||||
})?;
|
||||
let text_buffer = cx
|
||||
.background_spawn(async move {
|
||||
text::Buffer::new(ReplicaId::LOCAL, buffer_id, loaded.text)
|
||||
})
|
||||
.await;
|
||||
cx.insert_entity(reservation, |_| {
|
||||
Buffer::build(text_buffer, Some(loaded.file), Capability::ReadWrite)
|
||||
})
|
||||
})
|
||||
});
|
||||
|
||||
let load_file = worktree.update(cx, |worktree, cx| worktree.load_file(path.as_ref(), cx));
|
||||
cx.spawn(async move |this, cx| {
|
||||
let buffer = match load_buffer.await {
|
||||
Ok(buffer) => Ok(buffer),
|
||||
let path = path.clone();
|
||||
let buffer = match load_file.await.with_context(|| {
|
||||
format!("Could not open path: {}", path.display(PathStyle::local()))
|
||||
}) {
|
||||
Ok(loaded) => {
|
||||
let reservation = cx.reserve_entity::<Buffer>()?;
|
||||
let buffer_id = BufferId::from(reservation.entity_id().as_non_zero_u64());
|
||||
let text_buffer = cx
|
||||
.background_spawn(async move {
|
||||
text::Buffer::new(ReplicaId::LOCAL, buffer_id, loaded.text)
|
||||
})
|
||||
.await;
|
||||
cx.insert_entity(reservation, |_| {
|
||||
Buffer::build(text_buffer, Some(loaded.file), Capability::ReadWrite)
|
||||
})?
|
||||
}
|
||||
Err(error) if is_not_found_error(&error) => cx.new(|cx| {
|
||||
let buffer_id = BufferId::from(cx.entity_id().as_non_zero_u64());
|
||||
let text_buffer = text::Buffer::new(ReplicaId::LOCAL, buffer_id, "");
|
||||
@@ -657,9 +652,9 @@ impl LocalBufferStore {
|
||||
})),
|
||||
Capability::ReadWrite,
|
||||
)
|
||||
}),
|
||||
Err(e) => Err(e),
|
||||
}?;
|
||||
})?,
|
||||
Err(e) => return Err(e),
|
||||
};
|
||||
this.update(cx, |this, cx| {
|
||||
this.add_buffer(buffer.clone(), cx)?;
|
||||
let buffer_id = buffer.read(cx).remote_id();
|
||||
@@ -840,6 +835,7 @@ impl BufferStore {
|
||||
|
||||
entry
|
||||
.insert(
|
||||
// todo(lw): hot foreground spawn
|
||||
cx.spawn(async move |this, cx| {
|
||||
let load_result = load_buffer.await;
|
||||
this.update(cx, |this, cx| {
|
||||
|
||||
@@ -709,6 +709,7 @@ impl GitStore {
|
||||
repo.load_committed_text(buffer_id, repo_path, cx)
|
||||
});
|
||||
|
||||
// todo(lw): hot foreground spawn
|
||||
cx.spawn(async move |this, cx| {
|
||||
Self::open_diff_internal(this, DiffKind::Uncommitted, changes.await, buffer, cx)
|
||||
.await
|
||||
|
||||
@@ -9171,7 +9171,9 @@ async fn test_odd_events_for_ignored_dirs(
|
||||
repository_updates.lock().drain(..).collect::<Vec<_>>(),
|
||||
vec![
|
||||
RepositoryEvent::MergeHeadsChanged,
|
||||
RepositoryEvent::BranchChanged
|
||||
RepositoryEvent::BranchChanged,
|
||||
RepositoryEvent::StatusesChanged { full_scan: false },
|
||||
RepositoryEvent::StatusesChanged { full_scan: false },
|
||||
],
|
||||
"Initial worktree scan should produce a repo update event"
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user