fix(vloer): stop the whole process tree before capturing a candidate #184

Merged
ryangr0 merged 1 commit from ryangr0/vloer-stop-process-tree into development 2026-10-03 12:24:09 +00:00 AGit
Owner

The relay worker signalled only the direct harness child, replied
stopped:true without waiting after SIGKILL, and did not track
/__vloer/exec subprocesses at all. Grandchildren and exec subprocesses
kept running after a stop or a cancelled request, so files could still
change while captureInPlace exported the candidate.

The worker now starts the harness and every exec subprocess in its own
process group. A stop sends SIGTERM to the group, SIGKILL after a grace
period, and replies stopped:true only once no live member of the group
remains (zombies excluded, read from /proc). Otherwise it replies
stopped:false, /__vloer/run refuses to start a new child, and
captureInPlace refuses the export as stop_unconfirmed. Exec groups are
stopped on request cancellation, on an optional timeoutMs (the warm
sandbox clone now passes one), when the leader exits, and when the
worker shuts down.

Harness and exec subprocesses run in their own process groups; stop sends TERM then KILL to the group and replies stopped:true only when /proc shows no live member (zombies ignored because the worker is PID 1). Known limits: a grandchild that calls setsid() (e.g. git's auto-gc daemon) escapes the group; orphaned zombies accumulate because the image has no init (tini would fix that, an image change).

Verified with mise run verify on the pinned toolchain (all gates passed).

Ticket: https://vikunja.webgrip.dev/tasks/1743

🤖 Generated with Claude Code

The relay worker signalled only the direct harness child, replied stopped:true without waiting after SIGKILL, and did not track /__vloer/exec subprocesses at all. Grandchildren and exec subprocesses kept running after a stop or a cancelled request, so files could still change while captureInPlace exported the candidate. The worker now starts the harness and every exec subprocess in its own process group. A stop sends SIGTERM to the group, SIGKILL after a grace period, and replies stopped:true only once no live member of the group remains (zombies excluded, read from /proc). Otherwise it replies stopped:false, /__vloer/run refuses to start a new child, and captureInPlace refuses the export as stop_unconfirmed. Exec groups are stopped on request cancellation, on an optional timeoutMs (the warm sandbox clone now passes one), when the leader exits, and when the worker shuts down. Harness and exec subprocesses run in their own process groups; stop sends TERM then KILL to the group and replies stopped:true only when /proc shows no live member (zombies ignored because the worker is PID 1). Known limits: a grandchild that calls setsid() (e.g. git's auto-gc daemon) escapes the group; orphaned zombies accumulate because the image has no init (tini would fix that, an image change). Verified with `mise run verify` on the pinned toolchain (all gates passed). Ticket: https://vikunja.webgrip.dev/tasks/1743 🤖 Generated with [Claude Code](https://claude.com/claude-code)
fix(vloer): stop the whole process tree before capturing a candidate
Some checks failed
[Workflow] On Pull Request / release-policy (pull_request) Successful in 23s
[Workflow] On Pull Request / checks (pull_request) Failing after 5m57s
[Workflow] On Pull Request / warnings (pull_request) Has been cancelled
4d279abbc1
The relay worker signalled only the direct harness child, replied
stopped:true without waiting after SIGKILL, and did not track
/__vloer/exec subprocesses at all. Grandchildren and exec subprocesses
kept running after a stop or a cancelled request, so files could still
change while captureInPlace exported the candidate.

The worker now starts the harness and every exec subprocess in its own
process group. A stop sends SIGTERM to the group, SIGKILL after a grace
period, and replies stopped:true only once no live member of the group
remains (zombies excluded, read from /proc). Otherwise it replies
stopped:false, /__vloer/run refuses to start a new child, and
captureInPlace refuses the export as stop_unconfirmed. Exec groups are
stopped on request cancellation, on an optional timeoutMs (the warm
sandbox clone now passes one), when the leader exits, and when the
worker shuts down.

VIK-1743

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
ryangr0 merged commit 25f025253b into development 2026-10-03 12:24:09 +00:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
webgrip/unfold!184
No description provided.