feat: capacity resilience — ordered subnet/AZ + instance-type fallback#53
Merged
Conversation
…nstance types A single subnet-id + ec2-instance-type is a single point of failure: when that AZ has no capacity for that type, RunInstances fails and the whole workflow with it. Both inputs now accept comma-separated ordered fallback lists (single values behave byte-identically): ec2-instance-type: c7i.4xlarge,c6i.4xlarge,m7i.4xlarge subnet-id: subnet-aaa,subnet-bbb # different AZs - launchWithFallback walks type × subnet in order — every subnet/AZ is tried before downgrading the instance type (placement is cheaper than a hardware change). Capacity errors advance the chain; non-capacity errors (invalid AMI, auth, quota InstanceLimitExceeded) abort immediately so a misconfig doesn't burn the whole matrix; transient API errors retry within the cell. - classifyRunError buckets RunInstances errors into capacity / transient / fatal (spot capacity codes already included for #39). - retry.js withRetry gains an optional shouldRetry predicate (default unchanged), so a cell retries only transient errors. - New outputs instance-type-used / subnet-id-used report what actually launched. - Each failed placement logs a warn line (type, subnet, code); exhaustion fails with a summary of every attempt. Tests: classifyRunError buckets, launchWithFallback ordering (first-try, mid- chain, full-matrix exhaustion, fatal-abort, quota message), parseCsv, and withRetry shouldRetry (142 tests total). README "Capacity fallback" section + inputs/outputs tables and action.yml updated. Note: spot × fallback composition lands with #39 (spot support); the capacity codes and chain are already spot-ready. Closes #40 Signed-off-by: kurok <22548029+kurok@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #40 — roadmap (#49) Phase 1. Multiplies the value of spot (#39); independent of it for on-demand users.
Problem
One
subnet-id+ oneec2-instance-type= single point of failure. When that AZ has no capacity for that type (routine for larger/GPU types),RunInstancesfails and the workflow fails with it. Capacity errors are retriable placement problems — the action should own the retry.Solution
Both inputs accept comma-separated ordered fallback lists (single values behave byte-identically):
InsufficientInstanceCapacity,InsufficientHostCapacity,Unsupported, …) → advance to the next cell.InstanceLimitExceeded) → abort immediately so a misconfig doesn't burn the whole matrix; quota gets a targeted message.withRetry's newshouldRetrypredicate.Outputs
New
instance-type-used/subnet-id-usedreport what actually launched.Tests / build
tests/fallback.test.js:classifyRunErrorbuckets +launchWithFallbackordering — first-try success, mid-chain success (exact subnet-first-then-type call order), full-matrix exhaustion summary, fatal-abort, quota message. PlusparseCsvandwithRetryshouldRetry. 142 tests pass (was 128). Lint clean, dist rebuilt (verify-dist green).Wall-clock bound
Capacity errors advance without per-cell retry; only transient errors retry (bounded by
retry.js). A 9-cell chain of fast capacity rejections resolves in seconds, not minutes.Note on spot
Spot × fallback composition (run the chain for spot, then on-demand) lands with #39; the capacity codes and chain structure are already spot-ready. This PR is complete for on-demand.
Compatibility
Single-value
ec2-instance-type/subnet-idinputs collapse to a one-cell chain — byte-identical to today.