Skip to content

ci(phoenix): bound SLURM queue wait and combine build+test into one allocation - #1763

Open
sbryngelson wants to merge 4 commits into
masterfrom
ci/phoenix-queue-timeout-combined-alloc
Open

ci(phoenix): bound SLURM queue wait and combine build+test into one allocation#1763
sbryngelson wants to merge 4 commits into
masterfrom
ci/phoenix-queue-timeout-combined-alloc

Conversation

@sbryngelson

Copy link
Copy Markdown
Member

What & why

Phoenix CI has been failing as opaque ~8h cancelled jobs. Root cause, from the run logs, is SLURM queue starvation, not test failures:

  • Jobs sit PENDING for hours on the preemptible embers QOS (few idle GPU nodes on gpu-l40s), burning the entire timeout-minutes: 480 budget.
  • Build and Test are two separate SLURM submissions in one GitHub job, so we pay the queue lottery twice, back-to-back, under one 8h cap. In a representative run, Build queued ~4h15m and Test then never started before the cap.
  • A stuck job also holds a self-hosted phoenix-N runner slot for the full 8h, so unrelated PRs back up behind it.

Across the last 30 test.yml runs, Phoenix jobs were 61% cancelled / 32% success / 7% failure — but of jobs that actually ran to completion, ~83% passed. The red is overwhelmingly queue/infra, not code.

This PR does not try to buy more nodes; it makes the failure mode fast and legible, and halves each job's exposure to the queue.

Changes

A. Bound the queue wait (monitor_slurm_job.sh)

  • New SLURM_MAX_QUEUE_SECONDS (default 90m; 0 = old behaviour). If a job never leaves the queue, scancel it and fail fast with an explicit QUEUE STARVATION … infrastructure, not a code/test failure message (exit 75).
  • A job that has actually started (RUNNING/COMPLETING) but whose output file is merely NFS-delayed is exempt, so a job already doing work is never killed.
  • Effect: no more 8h zombies; stuck jobs release their runner slot in ~90m; queue problems are greppable instead of masquerading as cancelled.

B. Combine build+test into one Phoenix allocation (build-and-test.sh, submit-slurm-job.sh, test.yml)

  • Phoenix now submits a single build-and-test.sh allocation (build → test) so the scheduler queue wait is paid once instead of twice.
  • submit-slurm-job.sh exports the job_* vars so the child build.sh/test.sh inherit them, and gets a buildtest time budget (3h30m — test budget plus build headroom, kept modest to preserve embers backfill).
  • Every other cluster (Frontier CCE / AMD) is untouched: separate build/test steps, same times.

Testing

  • Stubbed-SLURM harness for A: a stuck PENDING job aborts with the starvation message and exit 75; a RUNNING job is exempt from the budget and proceeds to stream.
  • Verified job-type → time-budget → log-slug derivation for build-and-test / test / bench so Phoenix's combined build-and-test-*.out is still picked up by Print Logs.
  • bash -n on all three scripts; YAML validated.

Notes / follow-ups

  • The one tunable knob is buildtest_time (3h30m). If combined runs ever approach it, bump there.
  • A natural follow-up (deliberately out of scope): escalate embers → inferno after the queue-wait budget elapses, behind a flag, to spend SUs only when the free queue is starved.

Acknowledgement

  • I confirm this PR meets the above expectations and reflects my own understanding and real-world context.

…llocation

Phoenix CI jobs were failing as opaque ~8h 'cancelled': jobs sat PENDING for
hours on the preemptible 'embers' QOS, burning the 480-min job timeout and
holding self-hosted runner slots (which backs up unrelated PRs).

A) monitor_slurm_job.sh: bound the queue wait (SLURM_MAX_QUEUE_SECONDS, default
   90m). If a job never starts, scancel and fail fast with an explicit
   'queue starvation — infrastructure, not code' message and exit 75. A
   RUNNING job with a merely NFS-delayed output file is exempt.

B) Phoenix builds+tests in a single SLURM allocation (build-and-test.sh) so the
   scheduler queue wait is paid once instead of twice. submit-slurm-job.sh
   exports job_* so the child scripts inherit them; adds a 'buildtest' time
   budget (3h30m). Other clusters keep the separate build/test steps.
Copilot AI lite review requested due to automatic review settings August 25, 2026 16:08
@github-actions

Copy link
Copy Markdown

Claude Code Review

Head SHA: d95d626

Files changed:

  • 4
  • .github/scripts/monitor_slurm_job.sh
  • .github/scripts/submit-slurm-job.sh
  • .github/workflows/common/build-and-test.sh
  • .github/workflows/test.yml

Findings:

  • .github/workflows/common/build-and-test.sh:10-19: The header comment says the point of running in $SLURM_SUBMIT_DIR is "so build/ persists from build.sh into test.sh's --no-build run," but the actual invocation on line 19 is bash .github/workflows/common/test.sh with no arguments — no --no-build (or equivalent) flag is passed. If test.sh doesn't skip building by default, the Test phase will redundantly rebuild inside the same allocation, eating into the already-tight buildtest_time (03:30:00) budget and negating the "pay the queue wait once" rationale this file exists for.

Copilot AI 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.

Pull request overview

Warning

Copilot couldn't run its full agentic review because it didn't start before the timeout. Make sure your repository has a runner available, or add a copilot-code-review.yml file specifying one with the runs-on attribute. See the docs for more details.

Improves Phoenix CI reliability by failing fast on SLURM queue starvation and reducing exposure to queue wait by combining build+test into a single SLURM allocation.

Changes:

  • Add a bounded SLURM queue-wait budget with explicit “queue starvation” failure messaging.
  • Combine Phoenix build and test into a single SLURM allocation and update log slug collection.
  • Export job_* variables so wrapper scripts can run child phases that inherit job context.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.

File Description
.github/workflows/test.yml Routes Phoenix to a combined “Build & Test” SLURM submission and adjusts log printing to include the combined output.
.github/workflows/common/build-and-test.sh New wrapper that runs build then test inside one SLURM allocation.
.github/scripts/submit-slurm-job.sh Adds buildtest job type/time budget and exports job_* vars for child-process inheritance.
.github/scripts/monitor_slurm_job.sh Adds SLURM_MAX_QUEUE_SECONDS queue-wait limit and fails fast with a clear starvation message.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

# Combined build+test runs both phases in one allocation (one queue
# wait instead of two). It needs headroom for the build on top of the
# test budget; kept modest so it still backfills well under 'embers'.
buildtest_time="03:30:00"
Comment on lines +93 to +97
case "$job_type" in
bench) sbatch_time="#SBATCH -t $bench_time" ;;
buildtest) sbatch_time="#SBATCH -t $buildtest_time" ;;
*) sbatch_time="#SBATCH -t $test_time" ;;
esac
Comment on lines +116 to +126
if [ "$SLURM_MAX_QUEUE_SECONDS" -gt 0 ]; then
case "$state" in
RUNNING|COMPLETING) ;;
*)
waited=$(( $(date +%s) - queue_start ))
if [ "$waited" -ge "$SLURM_MAX_QUEUE_SECONDS" ]; then
abort_queue_starvation "$waited"
fi
;;
esac
fi
Addresses review: buildtest_time was only defined in the phoenix cluster
config, so a build-and-test.sh submission on any other cluster would hit an
unbound-variable crash under 'set -u'. Use ${buildtest_time:-$test_time} so the
combined job type is safe on every cluster (only phoenix uses it today).
…sabling

A mistyped override (e.g. '90m') would make the '[ -gt ]' comparison fail its
if-condition and silently skip the queue-wait budget — disabling the feature
without warning. Validate up front and exit 1 with a clear message.
@codecov

codecov Bot commented Aug 25, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 61.67%. Comparing base (e2f0e26) to head (ebc6df2).
⚠️ Report is 1 commits behind head on master.

Additional details and impacted files
@@           Coverage Diff           @@
##           master    #1763   +/-   ##
=======================================
  Coverage   61.67%   61.67%           
=======================================
  Files          84       84           
  Lines       21619    21619           
  Branches     3196     3196           
=======================================
  Hits        13334    13334           
  Misses       6093     6093           
  Partials     2192     2192           

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

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

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants