Skip to content

Commit b398b2b

Browse files
committed
🐛 Abort background tasks on Studio exit to prevent hanging
StudioApp now tracks background task handles and aborts them in a Drop implementation. This ensures the companion loading task and any other spawned tasks are properly cleaned up when the TUI exits, preventing the application from hanging while waiting for background work to complete.
1 parent f470abf commit b398b2b

File tree

1 file changed

+17
-2
lines changed

1 file changed

+17
-2
lines changed

src/studio/app/mod.rs

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,8 @@ pub struct StudioApp {
158158
last_click: Option<(std::time::Instant, u16, u16)>,
159159
/// Drag selection start info (panel, line number) for code view selection
160160
drag_start: Option<(PanelId, usize)>,
161+
/// Background task handles to abort on exit
162+
background_tasks: Vec<tokio::task::JoinHandle<()>>,
161163
}
162164

163165
impl StudioApp {
@@ -192,6 +194,7 @@ impl StudioApp {
192194
explicit_mode_set: false,
193195
last_click: None,
194196
drag_start: None,
197+
background_tasks: Vec::new(),
195198
}
196199
}
197200

@@ -805,7 +808,7 @@ impl StudioApp {
805808
}
806809

807810
/// Load companion service asynchronously for fast TUI startup
808-
fn load_companion_async(&self) {
811+
fn load_companion_async(&mut self) {
809812
let Some(repo) = &self.state.repo else {
810813
return;
811814
};
@@ -816,7 +819,7 @@ impl StudioApp {
816819
.get_current_branch()
817820
.unwrap_or_else(|_| "main".to_string());
818821

819-
tokio::spawn(async move {
822+
let handle = tokio::spawn(async move {
820823
let result = tokio::task::spawn_blocking(move || {
821824
use crate::companion::{BranchMemory, CompanionService};
822825
use super::state::CompanionSessionDisplay;
@@ -865,6 +868,9 @@ impl StudioApp {
865868
}
866869
}
867870
});
871+
872+
// Store handle so we can abort on exit
873+
self.background_tasks.push(handle);
868874
}
869875

870876
/// Run the TUI application
@@ -2600,6 +2606,15 @@ pub enum ExitResult {
26002606
Error(String),
26012607
}
26022608

2609+
impl Drop for StudioApp {
2610+
fn drop(&mut self) {
2611+
// Abort all background tasks to prevent hanging on exit
2612+
for handle in self.background_tasks.drain(..) {
2613+
handle.abort();
2614+
}
2615+
}
2616+
}
2617+
26032618
// ═══════════════════════════════════════════════════════════════════════════════
26042619
// Public Entry Point
26052620
// ═══════════════════════════════════════════════════════════════════════════════

0 commit comments

Comments
 (0)