Skip to content

Enhance Slurm-GCP resilience to capacity constraints and quota errors#5776

Open
vikramvs-gg wants to merge 5 commits into
GoogleCloudPlatform:developfrom
vikramvs-gg:slurm-resiliency
Open

Enhance Slurm-GCP resilience to capacity constraints and quota errors#5776
vikramvs-gg wants to merge 5 commits into
GoogleCloudPlatform:developfrom
vikramvs-gg:slurm-resiliency

Conversation

@vikramvs-gg

Copy link
Copy Markdown
Contributor

Description

This PR makes the Slurm-GCP provisioner resilient to GCP capacity constraints (stockouts) and quota limitations. It prevents wasted budget from partially provisioned jobs and handles failures gracefully by pushing jobs back into the queue without wedging the partition.

Key Changes

  1. Atomic Provisioning (minCount omission):
    • resume.py now omits minCount during the bulkInsert call for job-triggered requests. This enforces an "All or Nothing" provisioning behavior from GCP for job requests, entirely preventing the "partially provisioned" nodes issue that wastes budget while jobs hang.
  2. Transparent Error Handling (error_handler.py):
    • Introduced a standalone error handler script to accurately parse GCP API error codes (e.g., ZONE_RESOURCE_POOL_EXHAUSTED, QUOTA_EXCEEDED).
    • Slurm jobs are now updated with the exact raw GCP error message via AdminComment for immediate user visibility.
  3. Graceful Job Requeuing & Backoff:
    • Instead of marking nodes DOWN forever on a capacity error, resume.py executes a "Double Update" (state=down followed by state=power_down) to instantly clear the POWERING_UP state, bypassing Slurm's rigid ResumeTimeout.
    • The job is safely requeued to PENDING, and its StartTime is pushed back with a randomized jitter (3-5 minutes) to prevent aggressive API hammering during a prolonged stockout.

@gemini-code-assist

Copy link
Copy Markdown
Contributor

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request improves the resilience of the Slurm-GCP provisioner by implementing smarter error handling and atomic provisioning. By ensuring that job requests are treated as atomic units and providing a mechanism to gracefully handle GCP capacity constraints, the system now avoids wasteful partial node provisioning and reduces unnecessary API load during outages.

Highlights

  • Atomic Provisioning: Modified resume.py to omit minCount during bulkInsert for job-triggered requests, enforcing an 'All or Nothing' provisioning policy to prevent partial node allocation.
  • Enhanced Error Handling: Introduced error_handler.py to parse GCP API errors and provide actionable feedback, allowing the system to distinguish between transient issues like capacity exhaustion and other failures.
  • Graceful Job Requeuing: Implemented a robust failure recovery mechanism that clears node states, requeues affected jobs, and applies a randomized backoff to prevent API hammering during resource shortages.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize the Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counterproductive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@vikramvs-gg vikramvs-gg added enhancement New feature or request python Pull requests that update Python code release-key-new-features Added to release notes under the "Key New Features" heading. labels Jun 12, 2026

@gemini-code-assist gemini-code-assist 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.

Code Review

This pull request introduces a new error_handler.py script to classify GCP API errors (such as quota and capacity exhaustion) and handle them gracefully in Slurm. In resume.py, it implements atomic provisioning for job requests by omitting minCount, fixes a bug with duplicate node provisioning by intersecting job nodes with currently resuming nodes, and adds backoff logic for requeued jobs during failures. The review feedback suggests optimizing the job requeue wait logic by batching the checks to prevent sequential blocking delays, and simplifying the datetime and subprocess imports.

@vikramvs-gg
vikramvs-gg marked this pull request as ready for review June 13, 2026 09:20
@vikramvs-gg
vikramvs-gg requested a review from a team as a code owner June 13, 2026 09:20
@mufaqam-gcl
mufaqam-gcl requested a review from AdarshK15 June 16, 2026 05:58
@nick-stroud
nick-stroud requested a review from abbas1902 June 16, 2026 18:04

for job in jobs_to_requeue:
# To prevent the requeued job from immediately retrying and hammering
# the GCP API during a stockout, we calculate a randomized backoff (e.g. 3-5 mins) and

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Does this means that the order of jobs running might be shuffled around between initial attempt and the requeue since Slurm will strictly adhere to the new startTime?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Yes, some job shuffling is expected, but it's an intentional trade-off to prevent a thundering herd effect. The randomized jitter ensures that if multiple jobs fail simultaneously, they don't wake up at the exact same moment and overwhelm the GCP API.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I don't really understand why the randomness is necessary, we could do a consistent backoff if we want jobs spaced out and to not overwhelm a given API.

Jobs can often times be queued with the intention that they are dependent on the previous job's success. Yes while a user could combine these into a single job script, I think it probably teeters into unexpected behavior if jobs are run out of order of submission unless the reason can be justified.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

If we use a consistent backoff and 50 jobs fail at the same time, they will all wake up at the exact same second later on. That just creates another massive spike of API requests that will probably hit the quota limit again. The randomness is just there to prevent them from syncing up.

As for job ordering, Slurm doesn't actually guarantee submission order anyway since the backfill scheduler runs jobs out of order when nodes free up. If the jobs actually depend on each other, the user has to use dependency flag. If they do that, the jitter doesn't matter because that keeps the next job blocked until the first one finishes.

@abbas1902 abbas1902 Jul 14, 2026

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Was thinking more so linear rather than consistent. It is true Slurm doesn't make many guarantees over submission order, however I am concerned about arbitrary queue fragmentation.

Same idea with priority inversion, low priority jobs running before high priority jobs because of an unfavorable number pull.

I understand these are trade-offs you may be willing to make, but if I could suggest a few items:

  1. Some sort of guide/notice/documentation update about this behavior somewhere, it appears to not be opt in so it would be good if we had somewhere we could point to regarding why this behavior may occur. We can do some sort of follow up for this part.

  2. Could we narrow the 3-5 minute window? Maybe closer to 1 minute or less?

  3. Can we potentially preserve user intention around priority weighting? As you mention backfill will attempt to run jobs whenever it can. Maybe we can extract the priority information about the job and use that as part of the backoff calculation?

  4. What about heterogenous jobs/job arrays. I think this may cause some issues for such cases. For array jobs, this result in more ResumeProgram runs than initially expected right (due to the job scattering)?

It's good that this is directly connected to cases where we can match the error to quota exhaustion , I think if we can tighten the extremities a bit the drawbacks can be minimized.

@arpit974 arpit974 Jul 20, 2026

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.

+1 on point 2nd suggestions. Narrowing the backoff window to 60–120s (1–2 minutes) feels like a great middle ground here.

It keeps enough jitter to protect the GCP Compute API from a thundering herd of retries, while addressing the queue delay and priority inversion concerns raised above.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

  1. Added a note on this behaviour in docs/slurm-troubleshooting.md.
  2. Yes, narrowed it down to 1-2 minutes.
  3. If we take priority into calculating jitter, and if there are multiple huge high priority tasks, they will all receive a shorter jitter and may cause starvation for other jobs, and may even cause a thundering herd problem. The scope is to just prevent this by adding random jitter, As we have reduced the delay window, it will not keep jobs waiting in queue for too long.
  4. Yes it would have caused multiple runs, I have updated the logic to fetch the array/pack id and use it as a seed value for generating random jitter, so that all jobs in an array have same jitter and also added batching to reduce number of queries/updates.

@abbas1902 abbas1902 assigned AdarshK15 and unassigned AdarshK15 and abbas1902 Jun 23, 2026
@AdarshK15 AdarshK15 assigned abbas1902 and unassigned AdarshK15 Jul 1, 2026
@abbas1902 abbas1902 assigned AdarshK15 and unassigned AdarshK15 Jul 7, 2026
@abbas1902 abbas1902 assigned AdarshK15 and unassigned abbas1902 Jul 7, 2026
@AdarshK15 AdarshK15 assigned abbas1902 and unassigned AdarshK15 Jul 8, 2026
@abbas1902 abbas1902 assigned AdarshK15 and unassigned abbas1902 Jul 14, 2026
@AdarshK15
AdarshK15 requested a review from arpit974 July 16, 2026 07:00
# the GCP API during a stockout, we calculate a randomized backoff (e.g. 3-5 mins) and
# explicitly delay the job's next evaluation via the StartTime parameter.
delay_seconds = random.randint(180, 300)
backoff_time = (datetime.now() + timedelta(seconds=delay_seconds)).strftime("%Y-%m-%dT%H:%M:%S")

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.

Per the design doc, sbatch jobs should requeue with backoff, but interactive srun jobs should fail fast to the user terminal instead of hanging on a delayed StartTime.

Can we check batch_flag == 0 and skip the StartTime backoff for interactive jobs?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

When an srun job fails and error handler requests to requeue, Slurm instantly kills it instead of putting it back in PENDING. As we are only checking jobs in PENDING state, interactive jobs skip the backoff and fail fast.

@arpit974 arpit974 removed their assignment Jul 20, 2026
@AdarshK15 AdarshK15 assigned arpit974 and abbas1902 and unassigned AdarshK15 Jul 21, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request python Pull requests that update Python code release-key-new-features Added to release notes under the "Key New Features" heading.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants