mirror of
https://github.com/bytedance/deer-flow.git
synced 2026-10-28 06:00:38 +00:00
wait_for_sandbox_ready polls a sandbox's health endpoint until ready or a timeout-second budget elapses, but measured that budget on the wall clock (start_time = time.time(), while time.time() - start_time < timeout). A backward wall-clock step (NTP correction, VM resume, manual change) while polling keeps the loop running far past timeout -- and this runs on the sandbox acquisition path, so it pins the acquiring thread instead of giving up -- while a forward jump ends the wait early and destroys a sandbox that was about to become ready. The loop also only checked the deadline at the top and then blocked on a fixed 5s request timeout plus a fixed 1s sleep, so a single slow probe could overshoot timeout by up to ~6s; on the 5s acquisition path (local_backend) that roughly doubles the budget. Rework the wait to a monotonic deadline that clamps both the per-probe request timeout and the inter-probe sleep to the remaining budget (min(5.0, remaining) / min(1.0, remaining)), making the sync twin a faithful mirror of wait_for_sandbox_ready_async, which already does this on loop.time(). Add two deterministic regressions: one advances a scripted monotonic clock past the deadline while a fake wall clock steps backward (red on the old wall-clock loop), and one asserts the per-probe timeout and sleep are clamped to the remaining budget (red on the old fixed 5s/1s values). Signed-off-by: CorgiBoyG <111257566+CorgiBoyG@users.noreply.github.com>