Skip to content

[bugfix]: workers killed by a signal now log the reason - #1725

Open
KyleNeverGivesUp wants to merge 9 commits into
hao-ai-lab:mainfrom
KyleNeverGivesUp:report-signal-terminated-workers
Open

[bugfix]: workers killed by a signal now log the reason#1725
KyleNeverGivesUp wants to merge 9 commits into
hao-ai-lab:mainfrom
KyleNeverGivesUp:report-signal-terminated-workers

Conversation

@KyleNeverGivesUp

@KyleNeverGivesUp KyleNeverGivesUp commented Aug 19, 2026

Copy link
Copy Markdown
Contributor

Purpose

Workers that receive SIGTERM or SIGINT currently exit without reporting which
signal arrived or where execution was interrupted. The parent then sees only a
closed pipe and tells the user to consult a stack trace that was never emitted.
On DGX Spark/GB10 systems, a userspace OOM daemon can make this a routine and
otherwise opaque failure mode.

Changes

  • Preserve the received signal number in a private SystemExit subtype while
    retaining the historical argument-less exit status.
  • Install and guard the signal path early enough to cover worker startup,
    construction, and the busy loop.
  • Give spawned regression workers a bounded 30-second startup deadline so loaded ARM CI nodes do not fail at the PyTorch/FastVideo import boundary.
  • Log signal-specific guidance and the interrupted traceback, then re-raise so
    shutdown semantics remain unchanged.
  • Distinguish SIGINT from SIGTERM and avoid claiming that a SIGTERM stack is the
    root cause: it may come from an external process or parent cleanup after a
    different worker failed.
  • Document how to correlate Spark earlyoom/system logs, and note that SIGKILL
    and kernel OOM kills cannot be caught by Python.

Test coverage

The regression suite exercises both deterministic in-process injection and real
spawned Linux workers using an actual pipe, logging queue, SIGTERM/SIGINT
delivery, traceback forwarding, cleanup, and exit status. It also verifies that
unrelated SystemExit values are not intercepted.

pytest fastvideo/tests/worker/test_signal_terminated_worker_is_reported.py -q
11 passed, 14 warnings in 18.28s

PYTHONPATH="$PWD" bash .buildkite/scripts/unit_test.sh
961 passed, 7 skipped, 19 warnings in 40.79s

pre-commit run --files \
  fastvideo/worker/multiproc_executor.py \
  fastvideo/tests/worker/test_signal_terminated_worker_is_reported.py \
  docs/getting_started/installation/spark_performance.md
Passed

Scope

Other exception paths are unchanged. This deliberately handles only signals
installed by worker_main; it does not add a broad BaseException catch.

Checklist

  • Rebased onto current main
  • Added end-to-end subprocess regression coverage
  • Updated GB10 troubleshooting documentation
  • Ran the exact Buildkite unit lane locally
  • Ran repository pre-commit hooks on all changed paths

@mergify mergify Bot added type: bugfix Bug fix scope: inference Inference pipeline, serving, CLI scope: infra CI, tests, Docker, build labels Aug 19, 2026
@mergify

mergify Bot commented Aug 19, 2026

Copy link
Copy Markdown
Contributor

Merge Protections

🔴 1 of 1 protections blocking · waiting on 👀 reviews and 🤖 CI

Protection Waiting on
🔴 PR merge requirements 👀 reviews and 🤖 CI

🔴 PR merge requirements

Waiting for

  • #approved-reviews-by>=1
  • check-success=fastcheck-passed
  • check-success=full-suite-passed
This rule is failing.
  • #approved-reviews-by>=1
  • check-success=fastcheck-passed
  • check-success=full-suite-passed
  • check-success~=pre-commit
  • title~=(?i)^\[(feat|feature|bugfix|fix|refactor|perf|ci|doc|docs|misc|chore|kernel|new.?model|skill|skills|infra)\]

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: f3a05aef34

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread fastvideo/worker/multiproc_executor.py Outdated
@SolitaryThinker
SolitaryThinker force-pushed the report-signal-terminated-workers branch 2 times, most recently from c822207 to f38bbd4 Compare August 23, 2026 22:55
KyleNeverGivesUp and others added 4 commits August 25, 2026 23:08
`worker_main` installs a SIGTERM/SIGINT handler that raises `SystemExit`. That is
a `BaseException` and not an `Exception`, so it walks straight past the
`except Exception` below it. The worker exits having logged nothing, the parent
sees only a closed pipe, and the user gets:

  Exception: WorkerMultiprocProc initialization failed due to an exception in a
  background process. See stack trace for root cause.

with no stack trace anywhere. That is indistinguishable from a hang, a crash, an
out-of-memory kill or a deliberate shutdown.

It is not a rare path. A DGX Spark ships earlyoom configured as `-m 6,3 --prefer
python`, so it sends SIGTERM to python first once available memory drops below
six percent, which on that box is 7.3 GiB. Every memory-pressure failure there
reports nothing at all. The parent's own fallback in `shutdown` also terminates
workers that do not exit within five seconds, and that is equally silent today.

Add a `SystemExit` clause ahead of the broad one. It logs with the traceback and
re-raises, so exit semantics are unchanged and the parent still sees the pipe
close. The traceback is the useful part: a signal handler runs on top of whatever
the process was executing, so the frames are the frames that were interrupted,
which is the only clue to what the worker was doing when it was told to stop.
Recovering that by hand is what this change is meant to save, and it took most of
a day of instrumenting a loader that turned out not to be the problem.

fastvideo/tests/worker/test_signal_terminated_worker_is_reported.py: 3 passed,
and reverting this change fails two of them. Driving `worker_main` for real needs
a process, a pipe, a distributed init and a model, so the tests pin the structure
instead: the handler exists, it is ordered ahead of the broad one, and it
re-raises rather than swallowing the exit.
@SolitaryThinker
SolitaryThinker force-pushed the report-signal-terminated-workers branch from f38bbd4 to b1867a1 Compare August 26, 2026 06:10
@SolitaryThinker

Copy link
Copy Markdown
Collaborator

/merge

@SolitaryThinker

Copy link
Copy Markdown
Collaborator

/test full

@github-actions github-actions Bot added the ready PR is ready to merge label Aug 26, 2026
@mergify mergify Bot added the scope: docs Documentation label Aug 26, 2026
@SolitaryThinker

Copy link
Copy Markdown
Collaborator

/test full

@mergify

mergify Bot commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

This PR has merge conflicts with the base branch. Please rebase:

git fetch origin main
git rebase origin/main
# Resolve any conflicts, then:
git push --force-with-lease

@mergify mergify Bot added the needs-rebase PR has merge conflicts label Aug 26, 2026
Both sides added a bullet to the GB10 tuning list and git could not tell
they were about different things. hao-ai-lab#1715 documents that FastVideo now
disables the offload modes once a worker binds its device; this branch
documents that earlyoom prefers Python and that a worker's SIGTERM
traceback shows where it was interrupted, not why it was chosen. Neither
replaces the other, so both are kept, offload first.
@mergify mergify Bot removed the needs-rebase PR has merge conflicts label Aug 27, 2026
@mergify

mergify Bot commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

This PR has merge conflicts with the base branch. Please rebase:

git fetch origin main
git rebase origin/main
# Resolve any conflicts, then:
git push --force-with-lease

@mergify mergify Bot added the needs-rebase PR has merge conflicts label Aug 31, 2026
Resolves the one conflict, in spark_performance.md. hao-ai-lab#1793 appended an H3
sequential-load bullet to the same Running safely list that this branch appends
its earlyoom diagnostics bullet to. Both bullets are kept, H3 first. This
branch's bullet drops its opening sentence about earlyoom preferring Python
because the H3 bullet now states that.
@mergify mergify Bot removed the needs-rebase PR has merge conflicts label Aug 31, 2026
@mergify

mergify Bot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

This PR has merge conflicts with the base branch. Please rebase:

git fetch origin main
git rebase origin/main
# Resolve any conflicts, then:
git push --force-with-lease

@mergify mergify Bot added the needs-rebase PR has merge conflicts label Sep 1, 2026
Resolves the one conflict, in spark_performance.md. main rewrote the H3 entry
in the Running safely list, since lazy_module_load now owns the load split,
and added the TAEH3 and two-Spark bullets. Those are taken as is. This
branch's earlyoom diagnostics bullet is kept and moved to the end of the list.
@mergify mergify Bot removed the needs-rebase PR has merge conflicts label Sep 1, 2026
@SolitaryThinker SolitaryThinker removed the ready PR is ready to merge label Sep 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

scope: docs Documentation scope: inference Inference pipeline, serving, CLI scope: infra CI, tests, Docker, build type: bugfix Bug fix

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants