From bc1f2b47991c460ce5238770c0a5c80872695fd2 Mon Sep 17 00:00:00 2001 From: Roy Lin Date: Fri, 12 Jun 2026 14:18:44 +0800 Subject: [PATCH] fix(vm): event-style log drain for run_deferred_main Replace the fixed 150ms post-exit sleep with a bounded poll: wait until container.json stops growing for one 40ms interval (1s cap). Faster when the shim's log processor has already drained, safer when it lags. --- src/runtime/src/vm/mod.rs | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/src/runtime/src/vm/mod.rs b/src/runtime/src/vm/mod.rs index 41de141..770449d 100644 --- a/src/runtime/src/vm/mod.rs +++ b/src/runtime/src/vm/mod.rs @@ -530,8 +530,25 @@ impl VmManager { }; // Let the shim's log processor finish draining console.log into the json - // file (it flushes as the VM halts) before reading the captured output. - tokio::time::sleep(std::time::Duration::from_millis(150)).await; + // file (it flushes as the VM halts): poll until container.json stops + // growing for one interval (bounded at 1s) instead of a fixed sleep — + // fast when the drain is already done, safe when it lags. + let json_path = self + .home_dir + .join("boxes") + .join(&self.box_id) + .join("logs") + .join("container.json"); + let drain_start = std::time::Instant::now(); + let mut last_len = u64::MAX; + loop { + let len = std::fs::metadata(&json_path).map(|m| m.len()).unwrap_or(0); + if len == last_len || drain_start.elapsed() >= std::time::Duration::from_secs(1) { + break; + } + last_len = len; + tokio::time::sleep(std::time::Duration::from_millis(40)).await; + } let (stdout, stderr) = self.read_container_logs(); Ok(a3s_box_core::exec::ExecOutput { stdout,