mirror of
https://github.com/openai/codex.git
synced 2026-10-28 18:58:46 +00:00
## Why Stdio servers without `CODEX_MCP_PROTOCOL_VERSION` use the legacy handshake, even when they support MCP `2026-07-28`. ## What changed - Add the disabled-by-default `mcp_connection_sharing` feature to enable discovery for eligible local stdio servers. - Recover from failed or late discovery with a fresh handshake when needed, waiting for the previous helper to release resources before restarting. - Retain a working legacy connection when an upgrade attempt fails for the same account, except on authentication errors. - Keep tool catalogs separate by protocol and invalidate legacy catalogs when discovery negotiates the modern protocol. ## Testing Add regression coverage for failed and late discovery, legacy fallback, protocol-specific catalog reuse, message limits, and Windows descendant cleanup. GitOrigin-RevId: 36c675ef3b81d32fccf06ccbddda2312cfe602c9
50 lines
1.4 KiB
Rust
50 lines
1.4 KiB
Rust
use anyhow::Context;
|
|
use std::fs;
|
|
use std::path::Path;
|
|
use std::time::Duration;
|
|
|
|
pub async fn wait_for_pid_file(path: &Path) -> anyhow::Result<String> {
|
|
let pid = tokio::time::timeout(Duration::from_secs(2), async {
|
|
loop {
|
|
if let Ok(contents) = fs::read_to_string(path) {
|
|
let trimmed = contents.trim();
|
|
if !trimmed.is_empty() {
|
|
return trimmed.to_string();
|
|
}
|
|
}
|
|
tokio::time::sleep(Duration::from_millis(25)).await;
|
|
}
|
|
})
|
|
.await
|
|
.context("timed out waiting for pid file")?;
|
|
|
|
Ok(pid)
|
|
}
|
|
|
|
pub fn process_is_alive(pid: &str) -> anyhow::Result<bool> {
|
|
let status = std::process::Command::new("kill")
|
|
.args(["-0", pid])
|
|
.status()
|
|
.context("failed to probe process liveness with kill -0")?;
|
|
Ok(status.success())
|
|
}
|
|
|
|
async fn wait_for_process_exit_inner(pid: String) -> anyhow::Result<()> {
|
|
loop {
|
|
if !process_is_alive(&pid)? {
|
|
return Ok(());
|
|
}
|
|
tokio::time::sleep(Duration::from_millis(25)).await;
|
|
}
|
|
}
|
|
|
|
pub async fn wait_for_process_exit(pid: &str) -> anyhow::Result<()> {
|
|
let pid = pid.to_string();
|
|
// A stdio process group can keep its leader's PID for the two-second shutdown grace.
|
|
tokio::time::timeout(Duration::from_secs(5), wait_for_process_exit_inner(pid))
|
|
.await
|
|
.context("timed out waiting for process to exit")??;
|
|
|
|
Ok(())
|
|
}
|