Fix stopping one project killing all project terminal sessions
close_all_sessions() was called when stopping/removing/rebuilding a project, which shut down exec sessions for every project. Track container_id per session and use close_sessions_for_container() to only close sessions belonging to the target project. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -28,14 +28,12 @@ pub async fn remove_project(
|
|||||||
// Stop and remove container if it exists
|
// Stop and remove container if it exists
|
||||||
if let Some(project) = state.projects_store.get(&project_id) {
|
if let Some(project) = state.projects_store.get(&project_id) {
|
||||||
if let Some(ref container_id) = project.container_id {
|
if let Some(ref container_id) = project.container_id {
|
||||||
|
state.exec_manager.close_sessions_for_container(container_id).await;
|
||||||
let _ = docker::stop_container(container_id).await;
|
let _ = docker::stop_container(container_id).await;
|
||||||
let _ = docker::remove_container(container_id).await;
|
let _ = docker::remove_container(container_id).await;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Close any exec sessions
|
|
||||||
state.exec_manager.close_all_sessions().await;
|
|
||||||
|
|
||||||
state.projects_store.remove(&project_id)
|
state.projects_store.remove(&project_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -166,7 +164,7 @@ pub async fn stop_project_container(
|
|||||||
state.projects_store.update_status(&project_id, ProjectStatus::Stopping)?;
|
state.projects_store.update_status(&project_id, ProjectStatus::Stopping)?;
|
||||||
|
|
||||||
// Close exec sessions for this project
|
// Close exec sessions for this project
|
||||||
state.exec_manager.close_all_sessions().await;
|
state.exec_manager.close_sessions_for_container(container_id).await;
|
||||||
|
|
||||||
docker::stop_container(container_id).await?;
|
docker::stop_container(container_id).await?;
|
||||||
state.projects_store.update_status(&project_id, ProjectStatus::Stopped)?;
|
state.projects_store.update_status(&project_id, ProjectStatus::Stopped)?;
|
||||||
@@ -187,7 +185,7 @@ pub async fn rebuild_project_container(
|
|||||||
|
|
||||||
// Remove existing container
|
// Remove existing container
|
||||||
if let Some(ref container_id) = project.container_id {
|
if let Some(ref container_id) = project.container_id {
|
||||||
state.exec_manager.close_all_sessions().await;
|
state.exec_manager.close_sessions_for_container(container_id).await;
|
||||||
let _ = docker::stop_container(container_id).await;
|
let _ = docker::stop_container(container_id).await;
|
||||||
docker::remove_container(container_id).await?;
|
docker::remove_container(container_id).await?;
|
||||||
state.projects_store.set_container_id(&project_id, None)?;
|
state.projects_store.set_container_id(&project_id, None)?;
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ use super::client::get_docker;
|
|||||||
|
|
||||||
pub struct ExecSession {
|
pub struct ExecSession {
|
||||||
pub exec_id: String,
|
pub exec_id: String,
|
||||||
|
pub container_id: String,
|
||||||
pub input_tx: mpsc::UnboundedSender<Vec<u8>>,
|
pub input_tx: mpsc::UnboundedSender<Vec<u8>>,
|
||||||
shutdown_tx: mpsc::Sender<()>,
|
shutdown_tx: mpsc::Sender<()>,
|
||||||
}
|
}
|
||||||
@@ -140,6 +141,7 @@ impl ExecSessionManager {
|
|||||||
|
|
||||||
let session = ExecSession {
|
let session = ExecSession {
|
||||||
exec_id,
|
exec_id,
|
||||||
|
container_id: container_id.to_string(),
|
||||||
input_tx,
|
input_tx,
|
||||||
shutdown_tx,
|
shutdown_tx,
|
||||||
};
|
};
|
||||||
@@ -175,6 +177,20 @@ impl ExecSessionManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn close_sessions_for_container(&self, container_id: &str) {
|
||||||
|
let mut sessions = self.sessions.lock().await;
|
||||||
|
let ids_to_close: Vec<String> = sessions
|
||||||
|
.iter()
|
||||||
|
.filter(|(_, s)| s.container_id == container_id)
|
||||||
|
.map(|(id, _)| id.clone())
|
||||||
|
.collect();
|
||||||
|
for id in ids_to_close {
|
||||||
|
if let Some(session) = sessions.remove(&id) {
|
||||||
|
session.shutdown();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn close_all_sessions(&self) {
|
pub async fn close_all_sessions(&self) {
|
||||||
let mut sessions = self.sessions.lock().await;
|
let mut sessions = self.sessions.lock().await;
|
||||||
for (_, session) in sessions.drain() {
|
for (_, session) in sessions.drain() {
|
||||||
|
|||||||
Reference in New Issue
Block a user