Repository navigation
Conversation
After a task's process exited, `vp run` kept reading its stdout and stderr until end of file, and kept serving its IPC connections until every client disconnected. A process the task started that inherited the pipes, or connected to the runner, held them open, so the run waited until that process exited, which for a server is never. This affected cached tasks, whose output is always piped, and `--log=grouped` and `--log=labeled`. Once the task's process exits, its pipes now get two seconds (`LEFTOVER_GRACE`) to close, and then the IPC driver gets two seconds to drain. Anything still open belongs to a process the task left running: the runner stops reading, leaves the connection to be closed with the run's state, and doesn't cache the run (`ProcessLeftRunning`), since output or reports may be missing. `--last-details` says so. fspy already stops recording when the task's process exits. The IPC transport reads its FIFOs on tokio's blocking pool, and such a read can't be cancelled, so `vt` now exits without dropping its runtime, which would wait for it. vite-plus sends the result to JS before dropping its runtime and then calls `process.exit`. `vtt linger` leaves such a process behind for the new e2e fixture.
Dunqing
marked this pull request as ready for review
October 22, 2026 07:08
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Motivation
After a task's process exits,
vp runkeeps reading the task's stdout and stderr until end of file, and keeps its IPC server running until every client disconnects. Neither wait has a limit, and neither depends on the task: a process the task started can inherit the pipes or connect to the runner and hold them open.vp runthen waits until that process exits, which for a server is never. This affects cached tasks, whose output is always piped, and--log=groupedand--log=labeled.A common way to hit it is a test setup that starts
vp previewand stops it withchild.kill(). The kill reaches only thevpwrapper (voidzero-dev/vite-plus#3090), and the Vite server keeps its connection to the runner. With that setup as a cached task,vt runonmainwas still waiting whentimeoutkilled it at 25 s. With this change it exits after about 4 s, 2 s of which is the grace period below.Changes
run_childwaits for the child and drains its pipes at the same time. Once the child exits, the pipes getLEFTOVER_GRACE(2 s) to reach end of file, and then the IPC server gets 2 s to drain. Anything still open after that belongs to a process the task left running: the runner stops reading and stops polling the IPC driver, whose connections close with the run's state.CacheNotUpdatedReason::ProcessLeftRunning), since that process's output or its reports to the runner may be missing.vp run --last-detailsshows→ Not cached: the task exited, but a process it started kept its output or runner connection open. fspy already stops recording accesses once the task's own process exits.vtexits without dropping its tokio runtime. The IPC transport reads its FIFOs on the blocking pool, and dropping the runtime waits for a read that a leftover client keeps blocked. vite-plus already sends the result to JS before dropping its runtime and then callsprocess.exit.vtt linger <ms> <stdio|ipc>leaves a child holding stdout or an IPC connection, for the newleftover_processe2e fixture. Both cases time out onmain. They don't run on Windows, where the task's Job Object ends such processes once the task exits.A process the task left running that keeps writing to the piped output now gets a broken pipe after the grace period, where
vp runused to wait for it. Output inherited directly from the terminal (the default for uncached tasks) is unchanged.Related: #485 reports the same pipe wait on Windows, and #486 proposes polling the wait and the pipes together for it, which this change also does. It hasn't been tested on Windows. #724 also changes
run_child.