fix: let ctrl-c interrupt blocking job and agent collects
This commit is contained in:
6 files changed
+223
-3
No files matched your search
@@ -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");
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user