Fix ACP connection and thread leak (#35670)

When you switched away from an ACP thread, the `AcpThreadView` entity
(and thus thread, and subprocess) was leaked. This happened because we
were using `cx.processor` for the `list` state callback, which uses a
strong reference.

This PR changes the callback so that it holds a weak reference, and adds
some tests and assertions at various levels to make sure we don't
reintroduce the leak in the future.

Release Notes:

- N/A
This commit is contained in:
Agus Zubiaga 2025-08-05 19:10:51 -03:00 committed by GitHub
parent f27dc7dec7
commit b7469f5bc3
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 73 additions and 27 deletions

View file

@ -970,13 +970,7 @@ impl AgentPanel {
)
});
this.set_active_view(
ActiveView::ExternalAgentThread {
thread_view: thread_view.clone(),
},
window,
cx,
);
this.set_active_view(ActiveView::ExternalAgentThread { thread_view }, window, cx);
})
})
.detach_and_log_err(cx);
@ -1477,6 +1471,7 @@ impl AgentPanel {
let current_is_special = current_is_history || current_is_config;
let new_is_special = new_is_history || new_is_config;
let mut old_acp_thread = None;
match &self.active_view {
ActiveView::Thread { thread, .. } => {
@ -1488,6 +1483,9 @@ impl AgentPanel {
});
}
}
ActiveView::ExternalAgentThread { thread_view } => {
old_acp_thread.replace(thread_view.downgrade());
}
_ => {}
}
@ -1518,6 +1516,11 @@ impl AgentPanel {
self.active_view = new_view;
}
debug_assert!(
old_acp_thread.map_or(true, |thread| !thread.is_upgradable()),
"AcpThreadView leaked"
);
self.acp_message_history.borrow_mut().reset_position();
self.focus_handle(cx).focus(window);