Skip to content

feat(example): per-queue extension wiring; retire buildrunner/noop#193

Open
behinddwalls wants to merge 1 commit into
preetam/mock-ext-fakesfrom
preetam/mock-ext
Open

feat(example): per-queue extension wiring; retire buildrunner/noop#193
behinddwalls wants to merge 1 commit into
preetam/mock-ext-fakesfrom
preetam/mock-ext

Conversation

@behinddwalls
Copy link
Copy Markdown
Collaborator

@behinddwalls behinddwalls commented Jun 4, 2026

Summary

Why?

Demonstrate SubmitQueue's core premise — per-queue pluggable extensions —
in the example orchestrator, rather than wiring one implementation for
every queue, and make the fakes drivable end-to-end. Also document where
factory implementations and queue routing belong.

Stacked on the fakes PR, which adds the extension/*/fake packages this PR
wires in.

What?

  • Queue-major registry in example main.go: queueExtensions (one queue's
    full impl set) + queueRegistry (queue -> profile, with a default). Six
    thin Factory adapters resolve impls by Config.QueueName — all routing
    lives here in the wiring layer.
  • Per-queue profiles: test-queue (heuristic over lines changed),
    e2e-test-queue (composite scorer, no-conflict), plus a new
    e2e-conflict-error-queue that always fails conflict analysis. Edge
    integrations + build runner share a baseline; scorer/analyzer are wrapped
    by the decorator fakes (score-error marker / failing predicate).
  • Retire buildrunner/noop (subsumed by buildrunner/fake); switch the build
    controller unit test to buildfake.
  • queues.yaml: register e2e-conflict-error-queue.
  • CLAUDE.md: extensions hold contracts + impls only — factory
    implementations and routing live in the wiring layer; plus a TODO to
    evaluate promoting the registry into submitqueue/core later.

Test Plan

  • make test — 44/44 unit tests
  • make e2e-test — 1/1
  • make integration-test — 7/7
  • make check-gazelle / make check-tidy — clean
  • ✅ Live stack (make local-submitqueue-start): Ping OK; gateway rejects
    unknown queues; validated end-to-end — scorer passthrough (test-queue),
    scorer error (?sq-fake=score-error -> "fake: marked score error"), and
    conflict error (e2e-conflict-error-queue -> "fake: injected analyze
    error").

Stack

  1. refactor(storage): fold ChangeStore into storage, drop dead store #191
  2. refactor(change): persist typed change details from the change provider #195
  3. refactor(scorer): score batches over typed change details #196
  4. feat(extensions): fake implementations with error injection #197
  5. @ feat(example): per-queue extension wiring; retire buildrunner/noop #193
  6. refactor(conflict): take a batch of changes as analyzer input #202

// Trigger records the desired outcome for a new build (decided from a marker
// token in the head changes) and returns its unique build ID. The base changes
// and metadata are ignored.
func (r *runner) Trigger(_ context.Context, _ []entity.Change, head []entity.Change, _ entity.BuildMetadata) (entity.BuildID, error) {
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

what if trigger itself falils

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Good call — added a sq-fake=trigger-error marker: a head change URI carrying it now makes Trigger itself return an error (distinct from build-fail/build-error, which surface at Status). Fixed in #197 — the file moved there when this PR was split into fakes (#197) + wiring (#193).

// Status returns the outcome recorded for the build at Trigger time. Unknown
// build IDs default to succeeded, keeping the runner best-case for builds it did
// not create.
func (r *runner) Status(_ context.Context, buildID entity.BuildID) (entity.BuildStatus, entity.BuildMetadata, error) {
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

can we make buildID in certain way so we don't have maintain the state and can be just driven by what buildID contains

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Done — the runner is now stateless. Trigger encodes the terminal outcome into the BuildID (e.g. fake-build-fail-7), and Status derives the result purely from the BuildID it's given — the per-build outcome map + mutex are gone, so any runner instance can answer Status for an ID minted by any other (even across controllers/processes). Fixed in #197 (the file moved there after the split).

@behinddwalls behinddwalls force-pushed the preetam/mock-ext branch 2 times, most recently from 7c72f1e to 603dcc4 Compare June 4, 2026 20:16
@behinddwalls behinddwalls changed the base branch from main to scorer June 4, 2026 20:17
@behinddwalls behinddwalls changed the base branch from scorer to main June 4, 2026 20:32
@behinddwalls behinddwalls changed the base branch from main to preetam/mock-ext-fakes June 4, 2026 20:32
@behinddwalls behinddwalls changed the title feat: per-queue extension fakes with error injection in example feat(example): per-queue extension wiring; retire buildrunner/noop Jun 4, 2026
@behinddwalls behinddwalls marked this pull request as ready for review June 4, 2026 21:38
@behinddwalls behinddwalls requested review from a team and sbalabanov as code owners June 4, 2026 21:38
@behinddwalls behinddwalls force-pushed the preetam/mock-ext-fakes branch from 3471964 to d292387 Compare June 4, 2026 22:37
@behinddwalls behinddwalls changed the base branch from preetam/mock-ext-fakes to main June 5, 2026 02:20
@behinddwalls behinddwalls changed the base branch from main to preetam/mock-ext-fakes June 5, 2026 02:22
@behinddwalls behinddwalls force-pushed the preetam/mock-ext-fakes branch 2 times, most recently from 348a546 to dd07845 Compare June 5, 2026 03:35
## Summary

### Why?

Demonstrate SubmitQueue's core premise — per-queue pluggable extensions —
in the example orchestrator, rather than wiring one implementation for
every queue, and make the fakes drivable end-to-end. Also document where
factory implementations and queue routing belong.

Stacked on the fakes PR, which adds the extension/*/fake packages this PR
wires in.

### What?

- Queue-major registry in example main.go: queueExtensions (one queue's
  full impl set) + queueRegistry (queue -> profile, with a default). Six
  thin Factory adapters resolve impls by Config.QueueName — all routing
  lives here in the wiring layer.
- Per-queue profiles: test-queue (heuristic over lines changed),
  e2e-test-queue (composite scorer, no-conflict), plus a new
  e2e-conflict-error-queue that always fails conflict analysis. Edge
  integrations + build runner share a baseline; scorer/analyzer are wrapped
  by the decorator fakes (score-error marker / failing predicate).
- Retire buildrunner/noop (subsumed by buildrunner/fake); switch the build
  controller unit test to buildfake.
- queues.yaml: register e2e-conflict-error-queue.
- CLAUDE.md: extensions hold contracts + impls only — factory
  implementations and routing live in the wiring layer; plus a TODO to
  evaluate promoting the registry into submitqueue/core later.

## Test Plan

- ✅ `make test` — 44/44 unit tests
- ✅ `make e2e-test` — 1/1
- ✅ `make integration-test` — 7/7
- ✅ `make check-gazelle` / `make check-tidy` — clean
- ✅ Live stack (`make local-submitqueue-start`): Ping OK; gateway rejects
  unknown queues; validated end-to-end — scorer passthrough (test-queue),
  scorer error (`?sq-fake=score-error` -> "fake: marked score error"), and
  conflict error (e2e-conflict-error-queue -> "fake: injected analyze
  error").
@behinddwalls behinddwalls force-pushed the preetam/mock-ext-fakes branch from dd07845 to 7b45cdb Compare June 5, 2026 03:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants