Skip to content

Commit 1aa7503

Browse files
author
lijiuyang.5137
committed
Avoid blocking on incomplete MCP proxy connections
1 parent bcee479 commit 1aa7503

1 file changed

Lines changed: 46 additions & 2 deletions

File tree

src/runner.rs

Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ const PERMISSION_PROMPT_TIMEOUT: Duration = Duration::from_secs(8);
4343
const TTY_PERMISSION_TRANSCRIPT_GRACE: Duration = Duration::from_millis(1_500);
4444
const TTY_QUESTION_FORM_SETTLE: Duration = Duration::from_millis(250);
4545
const MCP_PROXY_RESPONSE_TIMEOUT: Duration = Duration::from_secs(30);
46+
const MCP_PROXY_REQUEST_LINE_TIMEOUT: Duration = Duration::from_millis(250);
4647
const PTY_TERMINATE_TIMEOUT: Duration = Duration::from_secs(5);
4748
const TTY_SESSION_LOCK_RETRY_TIMEOUT: Duration = Duration::from_secs(8);
4849
const TTY_SESSION_LOCK_RETRY_DELAY: Duration = Duration::from_millis(300);
@@ -901,10 +902,23 @@ async fn service_pending_mcp_proxy_requests_for_runtime(
901902
Err(error) if error.kind() == std::io::ErrorKind::WouldBlock => return Ok(()),
902903
Err(error) => return Err(error.into()),
903904
};
905+
stream.set_read_timeout(Some(MCP_PROXY_REQUEST_LINE_TIMEOUT))?;
904906
let mut line = String::new();
905907
{
906908
let mut reader = StdBufReader::new(stream.try_clone()?);
907-
reader.read_line(&mut line)?;
909+
match reader.read_line(&mut line) {
910+
Ok(_) => {}
911+
Err(error)
912+
if matches!(
913+
error.kind(),
914+
std::io::ErrorKind::WouldBlock | std::io::ErrorKind::TimedOut
915+
) =>
916+
{
917+
logging::event("mcp_proxy_skip reason=request_line_timeout");
918+
continue;
919+
}
920+
Err(error) => return Err(error.into()),
921+
}
908922
}
909923
if line.trim().is_empty() {
910924
continue;
@@ -1037,12 +1051,17 @@ async fn submit_prompt_and_tail_stream(
10371051
}
10381052

10391053
async fn submit_prompt_to_tty(process: &mut PtyProcess, prompt: &str) -> Result<()> {
1054+
logging::event(format!(
1055+
"prompt_submit start content_chars={}",
1056+
prompt.chars().count()
1057+
));
10401058
process.write_all(&bracketed_paste_input(prompt))?;
10411059
tokio::time::sleep(Duration::from_millis(120)).await;
10421060
if tty_output_still_editing_prompt(&process.recent_output(), prompt) {
10431061
logging::event("prompt_submit_retry reason=prompt_still_visible");
10441062
process.write_all(b"\r")?;
10451063
}
1064+
logging::event("prompt_submit done");
10461065
Ok(())
10471066
}
10481067

@@ -3517,6 +3536,10 @@ async fn prepare_tty_for_prompt(process: &mut PtyProcess) -> Result<()> {
35173536
}
35183537
if tty_output_accepts_prompt(&output) {
35193538
tokio::time::sleep(TTY_READY_SETTLE).await;
3539+
logging::event(format!(
3540+
"tty_ready stage=prepare elapsed_ms={}",
3541+
started.elapsed().as_millis()
3542+
));
35203543
return Ok(());
35213544
}
35223545
if started.elapsed() > TTY_STARTUP_TIMEOUT {
@@ -3576,7 +3599,10 @@ async fn prepare_tty_for_prompt_with_mcp(
35763599
}
35773600
if tty_output_accepts_prompt(&output) {
35783601
tokio::time::sleep(TTY_READY_SETTLE).await;
3579-
service_pending_mcp_proxy_requests_for_runtime(input, runtime, sdk_state).await?;
3602+
logging::event(format!(
3603+
"tty_ready stage=prepare_mcp elapsed_ms={}",
3604+
started.elapsed().as_millis()
3605+
));
35803606
return Ok(());
35813607
}
35823608
if started.elapsed() > TTY_STARTUP_TIMEOUT {
@@ -4300,6 +4326,24 @@ mod tests {
43004326
assert!(tty_output_accepts_prompt(output));
43014327
}
43024328

4329+
#[cfg(unix)]
4330+
#[tokio::test]
4331+
async fn sdk_mcp_proxy_connection_without_line_does_not_block_prepare_loop() {
4332+
use std::os::unix::net::UnixStream;
4333+
4334+
let runtime = create_sdk_mcp_runtime(vec!["conductor".to_owned()]).unwrap();
4335+
let _held_open = UnixStream::connect(&runtime.socket_path).unwrap();
4336+
let (_tx, mut rx) = mpsc::channel(1);
4337+
let mut sdk_state = SdkStreamState::new(&[]);
4338+
let started = Instant::now();
4339+
4340+
service_pending_mcp_proxy_requests_for_runtime(&mut rx, &runtime, &mut sdk_state)
4341+
.await
4342+
.unwrap();
4343+
4344+
assert!(started.elapsed() < Duration::from_secs(1));
4345+
}
4346+
43034347
#[test]
43044348
fn keeps_english_question_leader_in_tty_question_prompt() {
43054349
let output = "\

0 commit comments

Comments
 (0)