Skip to content

nixl_ep: Handle planned SIGTERM in elastic test - #1500

Merged
itayalroy merged 4 commits into
ai-dynamo:mainfrom
itayalroy:nixl_ep_ft_bench_exc
Apr 13, 2026
Merged

itayalroy merged 4 commits into
ai-dynamo:mainfrom
itayalroy:nixl_ep_ft_bench_exc

Conversation

@itayalroy

@itayalroy itayalroy commented Apr 7, 2026

Copy link
Copy Markdown
Contributor

elastic.py intentionally sends SIGTERM to simulate rank failure during the elastic test, but PR #1427 treats those expected exits as worker errors. Ignore planned SIGTERM exits when checking worker exit codes after the test completes.

Summary by CodeRabbit

  • Bug Fixes
    • Improved shutdown handling to restore default termination behavior and re-raise the termination after cleanup, ensuring a clean process exit.
    • Refined worker failure detection to ignore expected terminations during shutdown, reducing false failure reports and noisy alerts.

elastic.py intentionally sends SIGTERM to simulate
rank failure during the elastic test, but PR ai-dynamo#1427
treats those expected exits as worker errors. Ignore
planned SIGTERM exits when checking worker exit codes
after the test completes.
@github-actions

github-actions Bot commented Apr 7, 2026

Copy link
Copy Markdown

👋 Hi itayalroy! Thank you for contributing to ai-dynamo/nixl.

Your PR reviewers will review your contribution then trigger the CI to test your changes.

🚀

@itayalroy

Copy link
Copy Markdown
Contributor Author

/build

@itayalroy
itayalroy requested a review from brminich April 7, 2026 11:15
@itayalroy
itayalroy enabled auto-merge (squash) April 7, 2026 11:16
@itayalroy
itayalroy disabled auto-merge April 7, 2026 11:16
@itayalroy
itayalroy enabled auto-merge (squash) April 7, 2026 11:16
@coderabbitai

coderabbitai Bot commented Apr 7, 2026

Copy link
Copy Markdown
Contributor

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: f5d07b2f-be95-40cf-b2c1-0eb9e1446635

📥 Commits

Reviewing files that changed from the base of the PR and between 683bb90 and ec1c836.

📒 Files selected for processing (1)
  • examples/device/ep/tests/elastic/elastic.py

📝 Walkthrough

Walkthrough

Replaced the Python-level sys.exit(1) in handle_sigterm with restoring the SIGTERM handler to default and re-raising SIGTERM via signal.raise_signal(signum). In main(), worker exits with codes 0 and -signal.SIGTERM are treated as non-failures.

Changes

Cohort / File(s) Summary
Signal handling & worker exit logic
examples/device/ep/tests/elastic/elastic.py
handle_sigterm now calls signal.signal(signum, signal.SIG_DFL) and signal.raise_signal(signum) instead of sys.exit(1). main() treats p.exitcode in (0, -signal.SIGTERM) as non-failures (SIGTERM no longer counted as worker failure).

Sequence Diagram(s)

sequenceDiagram
    participant OS as OS Signal Layer
    participant Handler as Signal Handler\n(handle_sigterm)
    participant Process as Current Process
    participant Main as main()\n(manager)
    participant Worker as Worker Process

    rect rgba(244, 67, 54, 0.5)
    Note over OS,Handler: Old behavior
    OS->>Handler: SIGTERM
    Handler->>Handler: sys.exit(1)
    Handler->>Process: Process exits (code 1)
    Main->>Main: Inspect worker exitcode (!= 0)
    Main->>Main: Mark worker as failure
    end

    rect rgba(33, 150, 243, 0.5)
    Note over OS,Handler: New behavior
    OS->>Handler: SIGTERM
    Handler->>Handler: signal.signal(signum, SIG_DFL)
    Handler->>Handler: signal.raise_signal(signum)
    OS->>Process: Deliver default SIGTERM (terminate)
    Process->>Main: Worker exitcode == -signal.SIGTERM
    Main->>Main: Treat as non-failure
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐇 I nudged the signal, let defaults ring true,
No abrupt exit — a softer cue,
Workers bow out with expected grace,
Logs tidy up, the shutdown’s place,
I munch a leaf and watch the queue.

🚥 Pre-merge checks | ✅ 1 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Description check ❓ Inconclusive The description provides clear context about what changed (handling SIGTERM) and why (PR #1427 regression), but lacks structured sections matching the template. Restructure description using 'What?', 'Why?', and optionally 'How?' sections to match the repository template for clarity.
✅ Passed checks (1 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically describes the main change: handling planned SIGTERM signals in the elastic test for nixl_ep.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@examples/device/ep/tests/elastic/elastic.py`:
- Around line 652-653: The current check treats any -signal.SIGTERM as expected;
instead only ignore SIGTERM for workers we intentionally self-killed: add a
marker (e.g., a set like self_terminated or flag on the process) when you
perform the explicit self-kill (where handle_sigterm()-related self-kill is
invoked), then change the failure condition around p.exitcode in the loop to
treat -signal.SIGTERM as acceptable only if that process/index is in the
self_terminated marker; otherwise record it as a failure. Ensure
handle_sigterm() still re-raises for unexpected SIGTERMs and do not alter its
unconditional behavior for external signals.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: e3db93bd-6c3c-4cf4-b1a8-e401f35ba64b

📥 Commits

Reviewing files that changed from the base of the PR and between 86b8c72 and 8558bce.

📒 Files selected for processing (1)
  • examples/device/ep/tests/elastic/elastic.py

Comment thread examples/device/ep/tests/elastic/elastic.py
Comment thread examples/device/ep/tests/elastic/elastic.py Outdated
Comment thread examples/device/ep/tests/elastic/elastic.py

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

♻️ Duplicate comments (1)
examples/device/ep/tests/elastic/elastic.py (1)

70-71: 🧹 Nitpick | 🔵 Trivial

Document why the handler re-sends the signal.

Lines 70-71 are doing the right cleanup, but restoring SIG_DFL and re-issuing SIGTERM is not obvious at a glance. A short inline comment here would make it clear that the process is meant to terminate with the original signal-derived exit status, not via Python-level SystemExit.

In Python's `signal` module, what is the effect of restoring `signal.SIG_DFL` for `SIGTERM` and then calling `os.kill(os.getpid(), signal.SIGTERM)` from inside the signal handler?
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@examples/device/ep/tests/elastic/elastic.py` around lines 70 - 71, Add a
short inline comment just above the signal restoration and resend (the lines
calling signal.signal(signum, signal.SIG_DFL) and os.kill(os.getpid(), signum))
that explains that restoring SIG_DFL and re-issuing the original signal causes
the process to terminate using the default OS signal handling and exit status
(rather than returning to Python and raising SystemExit), ensuring the process
exits with the original signal-derived status; reference the signum variable and
the use of os.kill/os.getpid in the comment so readers can immediately
understand intent.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@examples/device/ep/tests/elastic/elastic.py`:
- Around line 70-71: Add a short inline comment just above the signal
restoration and resend (the lines calling signal.signal(signum, signal.SIG_DFL)
and os.kill(os.getpid(), signum)) that explains that restoring SIG_DFL and
re-issuing the original signal causes the process to terminate using the default
OS signal handling and exit status (rather than returning to Python and raising
SystemExit), ensuring the process exits with the original signal-derived status;
reference the signum variable and the use of os.kill/os.getpid in the comment so
readers can immediately understand intent.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: c678001b-2c65-44a8-acfd-ba9a85c65a05

📥 Commits

Reviewing files that changed from the base of the PR and between 8558bce and 8228a85.

📒 Files selected for processing (1)
  • examples/device/ep/tests/elastic/elastic.py

@itayalroy

Copy link
Copy Markdown
Contributor Author

/build

Comment thread examples/device/ep/tests/elastic/elastic.py Outdated
@itayalroy

Copy link
Copy Markdown
Contributor Author

/build

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants