fix(runtime-python): suppress Windows CMD/conhost flash on every launch (#4814) (#4848)

This commit is contained in:
YellowSnnowmann
2026-07-14 20:36:34 +05:30
committed by GitHub
parent 1cde3bdaf0
commit 574c22196f
3 changed files with 74 additions and 0 deletions
+34
View File
@@ -57,6 +57,10 @@ pub fn spawn_stdio_process(
.stdout(Stdio::piped())
.stderr(Stdio::piped())
.kill_on_drop(true);
// Suppress the Windows conhost flash. This process is (re)spawned on every
// launch to run the runtime python server, so without CREATE_NO_WINDOW a
// CMD window blinks up each time the app starts (GH-4814).
crate::openhuman::inference::local::process_util::apply_no_window(&mut cmd);
let child = cmd.spawn().with_context(|| {
format!(
@@ -76,3 +80,33 @@ pub fn spawn_stdio_process(
Ok(child)
}
#[cfg(test)]
mod tests {
use super::*;
use crate::openhuman::runtime_python::bootstrap::PythonSource;
// `apply_no_window` is a no-op off Windows, but exercising the spawn path
// end-to-end keeps the GH-4814 CREATE_NO_WINDOW hook covered. `/bin/cat
// <file>` prints the file and exits, so it stands in for the python child.
#[cfg(unix)]
#[tokio::test]
async fn spawn_stdio_process_launches_child() {
let dir = tempfile::tempdir().expect("tempdir");
let script = dir.path().join("payload.txt");
std::fs::write(&script, b"ok").expect("write payload");
let resolved = ResolvedPython {
bin_dir: PathBuf::from("/bin"),
python_bin: PathBuf::from("/bin/cat"),
version: "test".to_string(),
source: PythonSource::System,
};
let mut spec = PythonLaunchSpec::new(script);
spec.unbuffered = false; // `-u` is python-only; plain `cat <file>` here
let mut child = spawn_stdio_process(&resolved, &spec).expect("spawn cat");
let status = child.wait().await.expect("wait cat");
assert!(status.success());
}
}
@@ -258,6 +258,9 @@ async fn run_step(
cmd.env("HF_HOME", hf_home);
cmd.env("HF_HUB_DISABLE_TELEMETRY", "1");
cmd.kill_on_drop(true);
// Re-provisioning can run mid-session if the venv is missing/corrupted, so
// suppress the Windows conhost flash here too (GH-4814).
crate::openhuman::inference::local::process_util::apply_no_window(&mut cmd);
let output = match tokio::time::timeout(timeout, cmd.output()).await {
Ok(Ok(o)) => o,
@@ -314,4 +317,22 @@ mod tests {
.to_string_lossy()
.contains("answerdotai_ModernBERT-base"));
}
// Exercises the provisioning step path (including the GH-4814
// CREATE_NO_WINDOW hook, a no-op off Windows) with a trivial binary so it
// stays covered without a real python toolchain.
#[cfg(unix)]
#[tokio::test]
async fn run_step_runs_a_trivial_binary() {
let hf = tempfile::tempdir().expect("tempdir");
run_step(
Path::new("/bin/echo"),
&["ok"],
Duration::from_secs(30),
hf.path(),
"echo smoke",
)
.await
.expect("echo step succeeds");
}
}
@@ -181,6 +181,9 @@ async fn run_step(python_bin: &Path, args: &[&str], timeout: Duration, label: &s
let mut cmd = Command::new(python_bin);
cmd.args(args);
cmd.kill_on_drop(true);
// spaCy venv provisioning can re-run mid-session if the venv is missing or
// its ready marker is stale, so suppress the Windows conhost flash (GH-4814).
crate::openhuman::inference::local::process_util::apply_no_window(&mut cmd);
let output = match tokio::time::timeout(timeout, cmd.output()).await {
Ok(Ok(output)) => output,
@@ -397,4 +400,20 @@ mod tests {
assert_eq!(response.entities[0].label, "PERSON");
assert_eq!(response.nouns, vec!["migration"]);
}
// Exercises the venv provisioning step path (including the GH-4814
// CREATE_NO_WINDOW hook, a no-op off Windows) with a trivial binary so it
// stays covered without a real python toolchain.
#[cfg(unix)]
#[tokio::test]
async fn run_step_runs_a_trivial_binary() {
run_step(
Path::new("/bin/echo"),
&["ok"],
Duration::from_secs(30),
"echo smoke",
)
.await
.expect("echo step succeeds");
}
}