Skip to content

Commit ea01a2f

Browse files
author
John O'Hare
committed
feat: Auto-delete stale forum topics on cleanup
- Stale sessions now always delete their forum topic (not just close it), since a dead session has no reason to keep its topic visible - Falls back to closing topic if bot lacks delete permission - Simplified stale logic: check pane liveness on every cycle instead of waiting 24h — dead panes are cleaned up after 1h of inactivity - Normal session ends still respect auto_delete_topics config Co-Authored-By: DreamLabAI <github@thedreamlab.uk>
1 parent 850f3b9 commit ea01a2f

1 file changed

Lines changed: 21 additions & 23 deletions

File tree

src/bridge.rs

Lines changed: 21 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1029,28 +1029,26 @@ impl BridgeShared {
10291029
let sessions = self.sessions.lock().await;
10301030
sessions.expire_old_approvals();
10311031

1032-
// Check for stale sessions (1h without tmux, 24h with tmux)
1032+
// Get sessions idle for >1h
10331033
let candidates = sessions.get_stale_session_candidates(1);
10341034
drop(sessions);
10351035

10361036
for session in candidates {
1037-
if session.tmux_target.is_none() {
1038-
// No tmux info, clean up after 1h
1039-
tracing::info!(session_id = %session.id, "Cleaning up stale session (no tmux, >1h)");
1040-
self.cleanup_stale_session(&session, "inactivity timeout")
1041-
.await;
1042-
} else if let Some(target) = &session.tmux_target {
1043-
// Check if 24h+ old AND pane is dead
1044-
let age_hours = (chrono::Utc::now() - session.last_activity).num_hours();
1045-
if age_hours >= 24 {
1046-
let pane_alive =
1047-
InputInjector::is_pane_alive(target, session.tmux_socket.as_deref());
1048-
if !pane_alive {
1049-
tracing::info!(session_id = %session.id, "Cleaning up stale session (pane dead)");
1050-
self.cleanup_stale_session(&session, "pane no longer exists")
1051-
.await;
1052-
}
1037+
if let Some(target) = &session.tmux_target {
1038+
// Has tmux target — check if pane is still alive
1039+
let pane_alive =
1040+
InputInjector::is_pane_alive(target, session.tmux_socket.as_deref());
1041+
if !pane_alive {
1042+
tracing::info!(session_id = %session.id, target, "Cleaning up stale session (pane dead)");
1043+
self.cleanup_stale_session(&session, "tmux pane no longer exists")
1044+
.await;
10531045
}
1046+
// Pane alive = keep session, it may just be idle
1047+
} else {
1048+
// No tmux info at all — clean up after 1h of inactivity
1049+
tracing::info!(session_id = %session.id, "Cleaning up stale session (no tmux, >1h idle)");
1050+
self.cleanup_stale_session(&session, "inactivity timeout (no tmux)")
1051+
.await;
10541052
}
10551053
}
10561054
}
@@ -1062,20 +1060,20 @@ impl BridgeShared {
10621060
let _ = self
10631061
.bot
10641062
.send_message(
1065-
&format!(
1066-
"\u{1f50c} *Session ended* (terminal closed)\n\n_{}_",
1067-
reason
1068-
),
1063+
&format!("\u{1f50c} *Session cleaned up*\n\n_{}_", reason),
10691064
&SendOptions::default(),
10701065
Some(tid),
10711066
)
10721067
.await;
10731068

1074-
if self.config.auto_delete_topics {
1075-
let _ = self.bot.delete_forum_topic(tid).await;
1069+
// Stale sessions are truly dead — always delete the topic to keep the group clean.
1070+
// Normal session ends respect auto_delete_topics config; stale cleanup does not.
1071+
if self.bot.delete_forum_topic(tid).await.unwrap_or(false) {
1072+
tracing::info!(session_id = %session.id, %tid, "Deleted stale forum topic");
10761073
let sessions = self.sessions.lock().await;
10771074
sessions.clear_thread_id(&session.id);
10781075
} else {
1076+
// Fallback to close if delete fails (missing permissions)
10791077
let _ = self.bot.close_forum_topic(tid).await;
10801078
}
10811079
}

0 commit comments

Comments
 (0)