Skip to content

feat(orchestrator): poll builds and stop the ones nothing wants - #504

Open
behinddwalls wants to merge 1 commit into
preetam/speculation-build-dispatchfrom
preetam/speculation-buildsignal-paths
Open

feat(orchestrator): poll builds and stop the ones nothing wants#504
behinddwalls wants to merge 1 commit into
preetam/speculation-build-dispatchfrom
preetam/speculation-buildsignal-paths

Conversation

@behinddwalls

@behinddwalls behinddwalls commented Aug 3, 2026

Copy link
Copy Markdown
Collaborator

Summary

Why?

The poll loop was writing the path set on every terminal build — the third concurrent writer on a row where the speculate run, which holds a version across its whole Speculator call, was structurally the one to lose. And with the build stage now start-only, something has to enact cancellation.

What?

The poll loop becomes speculation's kill mechanism. On every poll of a non-terminal build it checks whether anything still wants the build running — batch not halted, the path's entry live and on this build's attempt, the attempt's link naming this very build — and asks the runner to cancel when nothing does. That one level-triggered check subsumes path cancels, batch halts, superseded attempts, and lost dispatch races: no cancel message exists to go stale, and a check that misses one poll is remade on the next.

It cannot cancel a wanted build: every "unwanted" condition is permanent once true, so a stale read only errs toward keeping, and store anomalies (a set, entry, or link that cannot legitimately be missing) also keep the build — a cancel is irreversible. The Cancel call is best-effort so a failure never kills the poll chain that would retry it. The path set is read as that kill list and never written.

Polls now partition on the build ID rather than the batch, and each re-poll mints a distinct message ID so the queue never dedups it away. The halted short-circuit stays removed: a cancelling batch reaches terminal only once its builds stop, and this loop is both what stops them and what watches them stop.

Test Plan

bazel test //submitqueue/orchestrator/... — every unwanted condition cancels; a wanted build never sees a Cancel; anomalies keep the build; a failed Cancel does not fail the poll; statuses recorded per terminal state; and no path-set write happens at all (the set store is wired read-only on the mock).

make fmt, make gazelle

Stack

  1. feat(speculation): generator contract and bestfirst impl #446
  2. feat(speculation): allocator contract and sticky impl #450
  3. feat(speculation): standard composed speculator #451
  4. feat(storage): speculation path set store #501
  5. feat(storage): path-build link store for per-path builds #502
  6. feat(orchestrator): dispatch builds per speculation path #503
  7. @ feat(orchestrator): poll builds and stop the ones nothing wants #504
  8. fix(orchestrator): mint distinct message IDs for cancel re-publishes #505
  9. feat(orchestrator): re-plan the queue from the Speculator each run #506
  10. feat(orchestrator)!: finalize batches from their speculation paths #507
  11. feat(orchestrator): compose per-queue speculators and turn speculation on #508

## Summary

### Why?

The poll loop was writing the path set on every terminal build — the third concurrent writer on a row where the speculate run, which holds a version across its whole Speculator call, was structurally the one to lose. And with the build stage now start-only, something has to enact cancellation.

### What?

The poll loop becomes speculation's kill mechanism. On every poll of a non-terminal build it checks whether anything still wants the build running — batch not halted, the path's entry live and on this build's attempt, the attempt's link naming this very build — and asks the runner to cancel when nothing does. That one level-triggered check subsumes path cancels, batch halts, superseded attempts, and lost dispatch races: no cancel message exists to go stale, and a check that misses one poll is remade on the next.

It cannot cancel a wanted build: every "unwanted" condition is permanent once true, so a stale read only errs toward keeping, and store anomalies (a set, entry, or link that cannot legitimately be missing) also keep the build — a cancel is irreversible. The Cancel call is best-effort so a failure never kills the poll chain that would retry it. The path set is read as that kill list and never written.

Polls now partition on the build ID rather than the batch, and each re-poll mints a distinct message ID so the queue never dedups it away. The halted short-circuit stays removed: a cancelling batch reaches terminal only once its builds stop, and this loop is both what stops them and what watches them stop.

## Test Plan

✅ `bazel test //submitqueue/orchestrator/...` — every unwanted condition cancels; a wanted build never sees a Cancel; anomalies keep the build; a failed Cancel does not fail the poll; statuses recorded per terminal state; and no path-set write happens at all (the set store is wired read-only on the mock).

✅ `make fmt`, `make gazelle`
@behinddwalls
behinddwalls force-pushed the preetam/speculation-buildsignal-paths branch from 37428c4 to c33a2d6 Compare August 4, 2026 05:11
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