fix: let ctrl-c interrupt blocking job and agent collects

This commit is contained in:
Dark-Alex-17 committed 2026-09-03 13:03:10 -06:00
1 parent dc41e9d5df
commit 3b01ae8f18
6 files changed
+223 -3

No files matched your search

+38
View File
@@ -68,6 +68,29 @@ pub async fn wait_abort_signal(abort_signal: &AbortSignal) {
}
}
/// Completes when the user interrupts: a SIGINT arrives, or the session's turn
/// signal is (or becomes) aborted. Needed because tools run in cooked mode --
/// tokio's global SIGINT handler (installed by the first `ctrl_c()` poll)
/// swallows the signal with nobody listening. On SIGINT, sets ctrl-c on the
/// session signal so the surrounding turn aborts too. With `None`, only the
/// SIGINT arm applies.
pub async fn wait_user_interrupt(session: Option<&AbortSignal>) {
let ctrl_c = async {
if tokio::signal::ctrl_c().await.is_err() {
std::future::pending::<()>().await;
}
};
match session {
Some(signal) => {
tokio::select! {
_ = ctrl_c => signal.set_ctrlc(),
_ = wait_abort_signal(signal) => {}
}
}
None => ctrl_c.await,
}
}
pub fn poll_abort_signal(abort_signal: &AbortSignal) -> Result<bool> {
if event::poll(Duration::from_millis(25))?
&& let Event::Key(key) = event::read()?
@@ -86,3 +109,18 @@ pub fn poll_abort_signal(abort_signal: &AbortSignal) -> Result<bool> {
}
Ok(false)
}
#[cfg(test)]
mod tests {
use super::*;
#[tokio::test]
async fn wait_user_interrupt_returns_promptly_on_preset_session_signal() {
let signal = create_abort_signal();
signal.set_ctrlc();
tokio::time::timeout(Duration::from_secs(1), wait_user_interrupt(Some(&signal)))
.await
.expect("must return promptly when the session signal is already set");
}
}