login session: only the child exiting finishes it, not one output pipe closing
This commit is contained in:
parent
c3ff0815ff
commit
25f93d41e1
1 changed files with 18 additions and 9 deletions
|
|
@ -25,7 +25,7 @@ struct State {
|
|||
/// First URL-looking substring we saw in the output. Surface this on the
|
||||
/// web UI as the link the operator should open.
|
||||
url: Option<String>,
|
||||
/// Set when the child has exited. The web UI uses this to know whether
|
||||
/// Set by `poll` when the child has exited. The web UI uses this to know whether
|
||||
/// the operator can still paste a code.
|
||||
finished: bool,
|
||||
/// Exit status note (e.g. "exited with code 0", "killed by signal 15"),
|
||||
|
|
@ -209,10 +209,10 @@ async fn pump<R: tokio::io::AsyncRead + Unpin>(
|
|||
// we'll miss it until EOF (acceptable for the URL surface — claude
|
||||
// prints the URL on its own line).
|
||||
match reader.read_line(&mut buf).await {
|
||||
Ok(0) => {
|
||||
state.lock().unwrap().finished = true;
|
||||
break;
|
||||
}
|
||||
// EOF means this pipe closed, not that the child exited: only
|
||||
// `poll` (via `try_wait`) may mark the session finished, or the
|
||||
// next state render would drop a login that is still running.
|
||||
Ok(0) => break,
|
||||
Ok(_) => {
|
||||
let mut s = state.lock().unwrap();
|
||||
if s.url.is_none()
|
||||
|
|
@ -225,9 +225,7 @@ async fn pump<R: tokio::io::AsyncRead + Unpin>(
|
|||
}
|
||||
Err(e) => {
|
||||
tracing::warn!(error = ?e, %tag, "login pump read error");
|
||||
let mut s = state.lock().unwrap();
|
||||
s.finished = true;
|
||||
s.exit_note = Some(format!("pump {tag} error: {e}"));
|
||||
state.lock().unwrap().exit_note = Some(format!("pump {tag} error: {e}"));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -277,7 +275,18 @@ impl Drop for LoginSession {
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::extract_url;
|
||||
use super::{State, extract_url, pump};
|
||||
use std::sync::{Arc, Mutex};
|
||||
use tokio::io::BufReader;
|
||||
|
||||
#[tokio::test]
|
||||
async fn a_closed_output_pipe_does_not_finish_the_session() {
|
||||
let state = Arc::new(Mutex::new(State::default()));
|
||||
|
||||
pump(BufReader::new(tokio::io::empty()), state.clone(), "stdout").await;
|
||||
|
||||
assert!(!state.lock().unwrap().finished);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn picks_first_https() {
|
||||
|
|
|
|||
Loading…
Reference in a new issue