mirror of
https://github.com/harivansh-afk/sandbox-agent.git
synced 2026-04-18 08:02:55 +00:00
feat: [US-039] - Fix leaked background tasks on browser stop
Store JoinHandles for the 3 CDP listener tasks (console, network request, network response) in BrowserRuntimeStateData and abort them in stop() before closing the CDP client. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
ffe6951d54
commit
f3b90cc606
1 changed files with 12 additions and 3 deletions
|
|
@ -80,6 +80,7 @@ struct BrowserRuntimeStateData {
|
||||||
recording_fps: Option<u32>,
|
recording_fps: Option<u32>,
|
||||||
console_messages: VecDeque<BrowserConsoleMessage>,
|
console_messages: VecDeque<BrowserConsoleMessage>,
|
||||||
network_requests: VecDeque<BrowserNetworkRequest>,
|
network_requests: VecDeque<BrowserNetworkRequest>,
|
||||||
|
cdp_listener_tasks: Vec<tokio::task::JoinHandle<()>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::fmt::Debug for BrowserRuntimeStateData {
|
impl std::fmt::Debug for BrowserRuntimeStateData {
|
||||||
|
|
@ -139,6 +140,7 @@ impl BrowserRuntime {
|
||||||
recording_fps: None,
|
recording_fps: None,
|
||||||
console_messages: VecDeque::new(),
|
console_messages: VecDeque::new(),
|
||||||
network_requests: VecDeque::new(),
|
network_requests: VecDeque::new(),
|
||||||
|
cdp_listener_tasks: Vec::new(),
|
||||||
})),
|
})),
|
||||||
config,
|
config,
|
||||||
}
|
}
|
||||||
|
|
@ -298,7 +300,7 @@ impl BrowserRuntime {
|
||||||
// Subscribe to console events and populate ring buffer
|
// Subscribe to console events and populate ring buffer
|
||||||
let console_rx = cdp.subscribe("Runtime.consoleAPICalled").await;
|
let console_rx = cdp.subscribe("Runtime.consoleAPICalled").await;
|
||||||
let inner_clone = self.inner.clone();
|
let inner_clone = self.inner.clone();
|
||||||
tokio::spawn(async move {
|
let console_handle = tokio::spawn(async move {
|
||||||
let mut rx = console_rx;
|
let mut rx = console_rx;
|
||||||
while let Some(params) = rx.recv().await {
|
while let Some(params) = rx.recv().await {
|
||||||
let raw_level =
|
let raw_level =
|
||||||
|
|
@ -371,7 +373,7 @@ impl BrowserRuntime {
|
||||||
let request_rx = cdp.subscribe("Network.requestWillBeSent").await;
|
let request_rx = cdp.subscribe("Network.requestWillBeSent").await;
|
||||||
let response_rx = cdp.subscribe("Network.responseReceived").await;
|
let response_rx = cdp.subscribe("Network.responseReceived").await;
|
||||||
let inner_clone2 = self.inner.clone();
|
let inner_clone2 = self.inner.clone();
|
||||||
tokio::spawn(async move {
|
let request_handle = tokio::spawn(async move {
|
||||||
let mut rx = request_rx;
|
let mut rx = request_rx;
|
||||||
while let Some(params) = rx.recv().await {
|
while let Some(params) = rx.recv().await {
|
||||||
let request_id = params
|
let request_id = params
|
||||||
|
|
@ -420,7 +422,7 @@ impl BrowserRuntime {
|
||||||
|
|
||||||
// Subscribe to network response events to update existing requests
|
// Subscribe to network response events to update existing requests
|
||||||
let inner_clone3 = self.inner.clone();
|
let inner_clone3 = self.inner.clone();
|
||||||
tokio::spawn(async move {
|
let response_handle = tokio::spawn(async move {
|
||||||
let mut rx = response_rx;
|
let mut rx = response_rx;
|
||||||
while let Some(params) = rx.recv().await {
|
while let Some(params) = rx.recv().await {
|
||||||
let request_id = params
|
let request_id = params
|
||||||
|
|
@ -454,6 +456,8 @@ impl BrowserRuntime {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
state.cdp_listener_tasks = vec![console_handle, request_handle, response_handle];
|
||||||
}
|
}
|
||||||
Err(problem) => {
|
Err(problem) => {
|
||||||
return Err(self.fail_start_locked(&mut state, problem).await);
|
return Err(self.fail_start_locked(&mut state, problem).await);
|
||||||
|
|
@ -513,6 +517,11 @@ impl BrowserRuntime {
|
||||||
state.state = BrowserState::Stopping;
|
state.state = BrowserState::Stopping;
|
||||||
self.write_runtime_log_locked(&state, "stopping browser runtime");
|
self.write_runtime_log_locked(&state, "stopping browser runtime");
|
||||||
|
|
||||||
|
// Abort CDP listener tasks before closing the client
|
||||||
|
for handle in state.cdp_listener_tasks.drain(..) {
|
||||||
|
handle.abort();
|
||||||
|
}
|
||||||
|
|
||||||
// Close CDP client
|
// Close CDP client
|
||||||
if let Some(ref cdp_client) = state.cdp_client.take() {
|
if let Some(ref cdp_client) = state.cdp_client.take() {
|
||||||
cdp_client.close().await;
|
cdp_client.close().await;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue