Skip to content

fleet coord: fall back to on-demand on a failed spot launch; watch the host groups until they are up - #1263

Merged
ejc3 merged 1 commit into
mainfrom
fleet-spot-fallback-fast
Oct 25, 2026
Merged

ejc3 merged 1 commit into
mainfrom
fleet-spot-fallback-fast

Conversation

@ejc3

@ejc3 ejc3 commented Oct 25, 2026 •

Copy link
Copy Markdown
Owner

Part of #1257 (GPU wall wake latency): a spot shortage reaches the on-demand group in seconds, and it reaches it at all once the fleet is awake.

The defect

The fallback (#1215) decided only while the power state was waking, after --spot-wait (120 s on staging). The EC2 half makes the fleet awake about 50 s into a wake, before the spot wait ends, so a spot group with no capacity was never moved to on demand. On staging, 2026-10-24 21:44 UTC, with a coordinator task definition that passed --on-demand-group (registered 14:07 that day), the spot group failed 12 launches over 13 minutes (UnfulfillableCapacity) and the on-demand group has no scaling activity at all.

What changed (src/fleet/coord/scale.rs)

  • The groups are watched (polled, instances reported, the fallback decided) from the wake, or the coordinator's start, until they hold --awake-capacity instances in service, also after the fleet is awake.
  • A short spot group falls back at once when Auto Scaling has recorded a failed launch of it since the wake raised it (DescribeScalingActivities, a Failed activity). Auto Scaling records one about 10 s after the raise (UnfulfillableCapacity at +7 s and MaxSpotInstanceCountExceeded on staging) and then keeps retrying spot without telling anyone. --spot-wait stays as the backstop and is the only rule when the activities cannot be read (logged once).
  • Logs: spot launch failed; falling back to on-demand now (with the activity's message) or spot group still short after the spot wait, then wake: host capacity in service with path = spot, on-demand or spot and on-demand, and since_wake_ms.
  • The poll while the groups come up is 2 s (was 5 s), so a failed launch is acted on at most 2 s after Auto Scaling records it.

Expected effect with no spot capacity: on-demand raised about 12 s into the wake instead of never (or 120 s if the fleet were still waking). The on-demand group then takes Auto Scaling's own reaction (11 s on 2026-10-25) and a cold host boot.

Evidence

test fails without the fix
a_failed_spot_launch_falls_back_to_on_demand_without_waiting (spot wait 60 s) with the failed-launch rule removed: desired {"fleet-hosts": 1} after 5s, calls [("fleet-hosts", 1)]
a_spot_group_still_short_once_the_fleet_is_awake_falls_back with the groups polled only while waking: same failure
failed_spot_launches_parse_from_the_scaling_activities new; the answer is shaped like staging's activities
a_failed_spot_launch_falls_back_without_the_wait, the_path_names_the_groups_the_hosts_came_from new

a_spot_group_short_after_the_wait_falls_back_to_on_demand_and_sleeps_to_zero now gives its "awake at start" phase a spot host in service: an awake fleet whose spot group has nothing now falls back, which that phase did not expect.

make test-unit FILTER="-E 'binary(test_fleet_coord) | (package(fcvm) & kind(lib) & test(/fleet::coord/))'"
Summary [5.648s] 68 tests run: 68 passed, 1099 skipped
make lint: advisories ok, bans ok, licenses ok, sources ok

Deploy

The coordinator's task role needs autoscaling:DescribeScalingActivities (ejc3/aws#670). Without it the coordinator logs the refusal once and falls back after the spot wait, which this PR still applies after the fleet is awake.

…e host groups until they are up

The on-demand fallback (#1215) waited --spot-wait (120 s on staging) and was decided only
while the fleet was waking. The EC2 half makes the fleet awake about 50 s into a wake
(53 s on 2026-10-25), so with no spot capacity the spot group stayed short and the
on-demand group was never raised: on 2026-10-24 21:44 the spot group failed 12 launches
over 13 minutes (UnfulfillableCapacity) and the on-demand group shows no activity.

- The groups are watched (polled, instances reported, the fallback decided) from the
  wake, or the coordinator's start, until they hold --awake-capacity instances in
  service, also after the fleet is awake.
- A short spot group falls back at once when Auto Scaling has recorded a failed launch of
  it since the wake raised it (DescribeScalingActivities, a Failed activity; Auto Scaling
  records one about 10 s after the raise and keeps retrying spot on its own). The spot
  wait stays as the backstop, and is the only rule when the activities cannot be read
  (logged once).
- Which rule fell back is logged ("spot launch failed; falling back to on-demand now"
  with the activity's message, or "spot group still short after the spot wait"), and
  when the groups are up, "wake: host capacity in service" with path=spot, on-demand, or
  spot and on-demand.
- The poll while the groups come up is 2 s (was 5 s).

Tests:
- a_failed_spot_launch_falls_back_to_on_demand_without_waiting: with the failed-launch
  rule removed it fails ("desired {fleet-hosts: 1} after 5s"); a failure from before the
  wake does not count.
- a_spot_group_still_short_once_the_fleet_is_awake_falls_back: with the groups polled
  only while waking it fails the same way.
- failed_spot_launches_parse_from_the_scaling_activities (an answer shaped like staging's),
  a_failed_spot_launch_falls_back_without_the_wait, the_path_names_the_groups_the_hosts_came_from.
- a_spot_group_short_after_the_wait_falls_back_to_on_demand_and_sleeps_to_zero gives its
  "awake at start" phase a spot host in service: an awake fleet whose spot group has
  nothing now falls back, which that phase did not expect.

The coordinator's role needs autoscaling:DescribeScalingActivities for the fast rule
(ejc3/aws); without it the coordinator logs the refusal once and keeps the spot wait.

make test-unit (test_fleet_coord, fcvm fleet::coord lib tests): 68 passed. make lint: ok.

Refs #1257
@ejc3

ejc3 commented Oct 25, 2026

Copy link
Copy Markdown
Owner Author

@codex review

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 25, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-25T12:21:02.622841Z 84c4fd0 Manual request
ℹ️ 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" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@coderabbitai

coderabbitai Bot commented Oct 25, 2026

Copy link
Copy Markdown

Warning

Review limit reached

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Next included review available in 44 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

Learn how review limits work.

Review configuration:

Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 8920921b-030c-406a-983a-00cd74b02630
Commits

Reviewing files that changed from the base of the PR and between dff9d0f and 84c4fd0.

Files selected for processing: 5
  • fleet/PROTOCOL.md
  • src/cli/args.rs
  • src/fleet/coord/mod.rs
  • src/fleet/coord/scale.rs
  • tests/test_fleet_coord.rs
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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.

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Bravo.

Reviewed commit: 84c4fd0470

ℹ️ 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".

ejc3 added a commit to ejc3/aws that referenced this pull request Oct 25, 2026
…ies (#670)

ejc3/fcvm#1263 moves a wake to the on-demand host group as soon as Auto Scaling records a
failed spot launch (UnfulfillableCapacity or MaxSpotInstanceCountExceeded, about 10 s
after the raise), instead of after --spot-wait (120 s). It reads that from
DescribeScalingActivities, which the coordinator's task role lacks; without it the
coordinator logs the refusal once and keeps the spot wait.

DescribeScalingActivities takes no resource-level permission, so it joins
DescribeAutoScalingGroups on Resource "*". scripts/test-fcvm-fleet.py pins the action list.

Tested: python3 scripts/test-fcvm-fleet.py (33 tests OK), terraform fmt -check.

Co-authored-by: ejc3 <ejc3@users.noreply.github.com>
@ejc3

ejc3 commented Oct 25, 2026

Copy link
Copy Markdown
Owner Author

NOT-A-DEFECT: the CodeRabbit comment is a review-limit notice, not a finding.

@ejc3
ejc3 merged commit 2840547 into main Oct 25, 2026
16 checks passed
@ejc3
ejc3 deleted the fleet-spot-fallback-fast branch October 25, 2026 15:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant