ep_cli: Fix "Too many open files" errors (#47243)

Closes #ISSUE

Release Notes:

- N/A *or* Added/Fixed/Improved ...
This commit is contained in:
Ben Kunkle 2026-01-20 14:41:31 -06:00 committed by GitHub
parent 2ccca66dc1
commit 37185ea864
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
15 changed files with 135 additions and 41 deletions

View file

@ -862,7 +862,10 @@ impl TestClient {
self.app_state.languages.clone(),
self.app_state.fs.clone(),
None,
init_worktree_trust,
project::LocalProjectFlags {
init_worktree_trust,
..Default::default()
},
cx,
)
})

View file

@ -92,7 +92,10 @@ pub fn run_component_preview() {
app_state.languages.clone(),
app_state.fs.clone(),
None,
false,
project::LocalProjectFlags {
init_worktree_trust: false,
..Default::default()
},
cx,
);

View file

@ -211,7 +211,10 @@ async fn setup_project(
app_state.languages.clone(),
app_state.fs.clone(),
None,
false,
project::LocalProjectFlags {
init_worktree_trust: false,
watch_global_configs: false,
},
cx,
)
});
@ -229,10 +232,16 @@ async fn setup_project(
let buffer_store = project.read_with(cx, |project, _| project.buffer_store().clone());
cx.subscribe(&buffer_store, {
let project = project.clone();
let project = project.downgrade();
let ep_store = ep_store.downgrade();
move |_, event, cx| match event {
BufferStoreEvent::BufferAdded(buffer) => {
ep_store.update(cx, |store, cx| store.register_buffer(&buffer, &project, cx));
let Some(project) = project.upgrade() else {
return;
};
ep_store
.update(cx, |store, cx| store.register_buffer(&buffer, &project, cx))
.ok();
}
_ => {}
}

View file

@ -22,7 +22,7 @@ use collections::HashSet;
use edit_prediction::EditPredictionStore;
use futures::channel::mpsc;
use futures::{SinkExt as _, StreamExt as _};
use gpui::{AppContext as _, Application, BackgroundExecutor};
use gpui::{AppContext as _, Application, BackgroundExecutor, Task};
use zeta_prompt::ZetaVersion;
use reqwest_client::ReqwestClient;
@ -674,23 +674,35 @@ fn main() {
}
}
if let Some(state) =
repo_examples.first().and_then(|e| e.state.as_ref())
{
let repo_url = &repo_examples.first().unwrap().spec.repository_url;
let project = repo_examples
.iter()
.find_map(|e| e.state.as_ref().map(|s| s.project.clone()))
.or_else(|| app_state.project_cache.get(repo_url));
if let Some(project) = project {
let mut cx = cx.clone();
let shutdown_task: Task<()> =
project.update(&mut cx, |project, cx| {
let lsp_store = project.lsp_store();
lsp_store.update(cx, |lsp_store, cx| {
lsp_store.shutdown_all_language_servers(cx)
})
});
shutdown_task.await;
if let Some(ep_store) =
cx.update(|cx| EditPredictionStore::try_global(cx))
{
let project = state.project.clone();
ep_store.update(&mut cx, |store, _| {
store.remove_project(&project);
});
}
}
app_state
.project_cache
.remove(&repo_examples.first().unwrap().spec.repository_url);
app_state.project_cache.remove(repo_url);
for example in &mut repo_examples {
example.state.take();
}

View file

@ -202,7 +202,10 @@ impl ExampleInstance {
app_state.languages.clone(),
app_state.fs.clone(),
None,
false,
project::LocalProjectFlags {
init_worktree_trust: false,
..Default::default()
},
cx,
);

View file

@ -33,7 +33,10 @@ pub fn init(app_state: Arc<AppState>, cx: &mut App) {
app_state.languages.clone(),
app_state.fs.clone(),
None,
false,
project::LocalProjectFlags {
init_worktree_trust: false,
..Default::default()
},
cx,
);

View file

@ -11036,6 +11036,10 @@ impl LspStore {
}
pub fn stop_all_language_servers(&mut self, cx: &mut Context<Self>) {
self.shutdown_all_language_servers(cx).detach();
}
pub fn shutdown_all_language_servers(&mut self, cx: &mut Context<Self>) -> Task<()> {
if let Some((client, project_id)) = self.upstream_client() {
let request = client.request(proto::StopLanguageServers {
project_id,
@ -11043,10 +11047,12 @@ impl LspStore {
also_servers: Vec::new(),
all: true,
});
cx.background_spawn(request).detach_and_log_err(cx);
cx.background_spawn(async move {
request.await.ok();
})
} else {
let Some(local) = self.as_local_mut() else {
return;
return Task::ready(());
};
let language_servers_to_stop = local
.language_server_ids
@ -11061,7 +11067,6 @@ impl LspStore {
cx.background_spawn(async move {
futures::future::join_all(tasks).await;
})
.detach();
}
}

View file

@ -164,6 +164,21 @@ pub use lsp_store::{
pub use toolchain_store::{ToolchainStore, Toolchains};
const MAX_PROJECT_SEARCH_HISTORY_SIZE: usize = 500;
#[derive(Clone, Copy, Debug)]
pub struct LocalProjectFlags {
pub init_worktree_trust: bool,
pub watch_global_configs: bool,
}
impl Default for LocalProjectFlags {
fn default() -> Self {
Self {
init_worktree_trust: true,
watch_global_configs: true,
}
}
}
pub trait ProjectItem: 'static {
fn try_open(
project: &Entity<Project>,
@ -1088,7 +1103,7 @@ impl Project {
languages: Arc<LanguageRegistry>,
fs: Arc<dyn Fs>,
env: Option<HashMap<String, String>>,
init_worktree_trust: bool,
flags: LocalProjectFlags,
cx: &mut App,
) -> Entity<Self> {
cx.new(|cx: &mut Context<Self>| {
@ -1097,7 +1112,7 @@ impl Project {
.detach();
let snippets = SnippetProvider::new(fs.clone(), BTreeSet::from_iter([]), cx);
let worktree_store = cx.new(|_| WorktreeStore::local(false, fs.clone()));
if init_worktree_trust {
if flags.init_worktree_trust {
trusted_worktrees::track_worktree_trust(
worktree_store.clone(),
None,
@ -1185,6 +1200,7 @@ impl Project {
fs.clone(),
worktree_store.clone(),
task_store.clone(),
flags.watch_global_configs,
cx,
)
});
@ -1899,7 +1915,10 @@ impl Project {
Arc::new(languages),
fs,
None,
false,
LocalProjectFlags {
init_worktree_trust: false,
..Default::default()
},
cx,
)
});
@ -1956,7 +1975,10 @@ impl Project {
Arc::new(languages),
fs,
None,
init_worktree_trust,
LocalProjectFlags {
init_worktree_trust,
..Default::default()
},
cx,
)
});

View file

@ -691,6 +691,7 @@ impl SettingsObserver {
fs: Arc<dyn Fs>,
worktree_store: Entity<WorktreeStore>,
task_store: Entity<TaskStore>,
watch_global_configs: bool,
cx: &mut Context<Self>,
) -> Self {
cx.subscribe(&worktree_store, Self::on_worktree_store_event)
@ -787,16 +788,24 @@ impl SettingsObserver {
_user_settings_watcher: None,
_editorconfig_watcher: Some(_editorconfig_watcher),
project_id: REMOTE_SERVER_PROJECT_ID,
_global_task_config_watcher: Self::subscribe_to_global_task_file_changes(
fs.clone(),
paths::tasks_file().clone(),
cx,
),
_global_debug_config_watcher: Self::subscribe_to_global_debug_scenarios_changes(
fs.clone(),
paths::debug_scenarios_file().clone(),
cx,
),
_global_task_config_watcher: if watch_global_configs {
Self::subscribe_to_global_task_file_changes(
fs.clone(),
paths::tasks_file().clone(),
cx,
)
} else {
Task::ready(())
},
_global_debug_config_watcher: if watch_global_configs {
Self::subscribe_to_global_debug_scenarios_changes(
fs.clone(),
paths::debug_scenarios_file().clone(),
cx,
)
} else {
Task::ready(())
},
}
}

View file

@ -160,7 +160,10 @@ fn main() -> Result<(), anyhow::Error> {
registry,
fs,
Some(Default::default()),
false,
project::LocalProjectFlags {
init_worktree_trust: false,
..Default::default()
},
cx,
))
};

View file

@ -659,7 +659,10 @@ pub async fn open_remote_project(
app_state.languages.clone(),
app_state.fs.clone(),
None,
false,
project::LocalProjectFlags {
init_worktree_trust: false,
..Default::default()
},
cx,
);
cx.new(|cx| {

View file

@ -195,6 +195,7 @@ impl HeadlessProject {
fs.clone(),
worktree_store.clone(),
task_store.clone(),
true,
cx,
);
observer.shared(REMOTE_SERVER_PROJECT_ID, session.clone(), cx);

View file

@ -1659,7 +1659,7 @@ impl Workspace {
app_state.languages.clone(),
app_state.fs.clone(),
env,
true,
Default::default(),
cx,
);

View file

@ -222,7 +222,10 @@ fn run_visual_tests(project_path: PathBuf, update_baseline: bool) -> Result<()>
app_state.languages.clone(),
app_state.fs.clone(),
None,
false,
project::LocalProjectFlags {
init_worktree_trust: false,
..Default::default()
},
cx,
)
});
@ -900,7 +903,10 @@ fn run_breakpoint_hover_visual_tests(
app_state.languages.clone(),
app_state.fs.clone(),
None,
false,
project::LocalProjectFlags {
init_worktree_trust: false,
..Default::default()
},
cx,
)
});
@ -1212,7 +1218,10 @@ import { AiPaneTabContext } from 'context';
app_state.languages.clone(),
app_state.fs.clone(),
None,
false,
project::LocalProjectFlags {
init_worktree_trust: false,
..Default::default()
},
cx,
)
});
@ -1696,7 +1705,10 @@ fn run_subagent_visual_tests(
app_state.languages.clone(),
app_state.fs.clone(),
None,
false,
project::LocalProjectFlags {
init_worktree_trust: false,
..Default::default()
},
cx,
)
});
@ -2018,7 +2030,10 @@ fn run_agent_thread_view_test(
app_state.languages.clone(),
app_state.fs.clone(),
None,
false,
project::LocalProjectFlags {
init_worktree_trust: false,
..Default::default()
},
cx,
)
});

View file

@ -82,7 +82,10 @@ pub async fn open_test_workspace(
app_state.languages.clone(),
app_state.fs.clone(),
None,
false,
project::LocalProjectFlags {
init_worktree_trust: false,
..Default::default()
},
cx,
)
});