Skip to content

perf(control): index the global queue-gauge order; tolerate bad runs_on - #373

Open
Bnjoroge1 wants to merge 4 commits into
Bnjoroge/control-migrationsfrom
Bnjoroge/queue-gauges
Open

Bnjoroge1 wants to merge 4 commits into
Bnjoroge/control-migrationsfrom
Bnjoroge/queue-gauges

Conversation

@Bnjoroge1

@Bnjoroge1 Bnjoroge1 commented Oct 5, 2026 •

Copy link
Copy Markdown
Collaborator

Stacked on #372 (control migrations). Fixes the PR #347 queue-gauge report.

What changed

  • Global gauge queries: pg/lifecycle.rs::queue_gauges now LIMIT 1 via query_opt (only the first row was ever used) and parses runs_on tolerantly (unwrap_or_default — bad JSON no longer fails the gauge). Same treatment for the live gauge paths: dispatch.rs::ready_front_labels_on, dispatch.rs::cancel_outcome_gauges, lookups.rs::queue_stats.
  • Lite: next_ready_labels/queue_stats already LIMIT 1 + tolerant; the missing piece was the index.
  • Index: jobs_ready_global ON jobs(priority DESC, run_order, job_order, run_id, job_id) WHERE queue_state = ready — added to both schema.sql copies, docs, and migration V2026100506 (registered in MIGRATIONS by this branch). The per-pool jobs_ready index is untouched (claim path keeps using it).
  • Tests: shared suite queue_gauges_report_the_global_front (both backends); lite EXPLAIN asserts index-fed, no temp B-tree, plus in-place migration + malformed runs_on; pg EXPLAIN (Index Scan using jobs_ready_global, no Sort) + non-list runs_on. Verified ad hoc against disposable PG and SQLite with 100k rows; the repo test suite is the CI gate.

Notes

  • 2026100505 is reserved for a pending artifact-catalog migration; the ledger intentionally jumps 0504 → 0506. Refinery applies in ascending order, so 0505 landing later is applied normally.
  • pg::queue_gauges has no callers on the base (dead code); it was fixed as requested — the live gauge paths are the three above. Decide separately whether to wire it in or drop it.
  • Build/test gate: not yet run on this exact commit locally; CI on this PR is the first full pass.

Summary by cubic

Makes the global queue-gauge reads index-fed instead of sorting the whole ready queue on every call, and stops the gauges from failing on a runs_on that isn't a JSON string list.

The jobs_ready_global partial index serves the global dispatch order (priority DESC, run_order, job_order plus run/job tie-breakers) on both backends, while the per-pool claim path keeps jobs_ready unchanged. The pg front read now takes LIMIT 1, and a bad runs_on reports the depth with no front labels rather than erroring. Tests were ported to the current CancelOutcome contract and verified via EXPLAIN that the gauge plans are index-fed with no Sort node.

Migration

  • Ships as V2026100506 in both dialects; the ledger jumps 0504 → 0506, with 0505 reserved for a pending artifact-catalog migration.
  • pg::queue_gauges has no callers on the base (dead code): it was fixed as requested, but decide separately whether to wire it in or drop it.

Written for commit df57951. Summary will update on new commits.

View guided diff Turn on auto-fix

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex usage limits have been reached for code reviews. Please check with the admins of this repo to increase the limits by adding credits.
Credits must be used to enable repository wide code reviews.

@coderabbitai

coderabbitai Bot commented Oct 5, 2026 •

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration
  • Configuration used: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 6a3161db-081e-4f67-acda-72ff0bb434ec

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
  • Autopilot · 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.

@Bnjoroge1
Bnjoroge1 force-pushed the Bnjoroge/queue-gauges branch from 4663364 to 51c2192 Compare October 6, 2026 19:50
@Bnjoroge1
Bnjoroge1 force-pushed the Bnjoroge/control-migrations branch from dfff47d to f67e4f7 Compare October 7, 2026 04:33
@Bnjoroge1
Bnjoroge1 force-pushed the Bnjoroge/queue-gauges branch 5 times, most recently from c2fc877 to 2facb70 Compare October 7, 2026 05:55
@Bnjoroge1
Bnjoroge1 force-pushed the Bnjoroge/queue-gauges branch 2 times, most recently from d821148 to 8b4d963 Compare October 7, 2026 09:24
Bnjoroge1 and others added 4 commits October 7, 2026 10:58
…d runs_on

The queue-depth/front gauges read the ready set in the global dispatch
order (priority DESC, run_order, job_order; the cancel and status reads
append the run_id, job_id tie-breakers). The per-pool `jobs_ready` index
leads with pool_key, so every global gauge call sorted the whole ready
set. A new partial index, `jobs_ready_global`, feeds that order on both
backends; the claim path keeps reading `jobs_ready` (its order is that
index's key, unchanged).

The pg `queue_gauges` front read now takes `LIMIT 1` — only the first row
was ever used — and every gauge parse (queue_gauges, the cancel path,
ready_front_labels, queue_stats) tolerates a stored `runs_on` that is not
a JSON string list instead of failing the command. Lite already read
`LIMIT 1` and parsed tolerantly; it gets the matching index.

Schema: the index ships as migration `V2026100506__jobs_ready_global_index`
in both dialects (Refinery embedded, forward-only) plus `schema.sql`,
`lite/schema.sql`, `docs/control-schema.sql` and the chartdb catalog. No
schema-version bump here: the migration runner lands with the
control-migrations branch and this change stacks after it.

Verified with EXPLAIN on populated, analyzed tables: Postgres
`Index Scan using jobs_ready_global` with no Sort node, and the claim order
still `Index Scan using jobs_ready`; SQLite `SCAN jobs USING INDEX
jobs_ready_global` with no temp b-tree. Tests: shared suite front-label
test (both backends), lite plan + in-place migration + malformed runs_on,
pg plan + non-list runs_on.
The rebase onto main moved the command-outcome gauges to the current
contract: `SubmitOutcome` reports `queued_jobs` (there is no
`queue_depth`), and `CancelOutcome` carries `queue_nonempty: bool` (the
global ready set, computed after the transition) plus `next_runs_on`. The
suite test, the lite malformed-`runs_on` test and the pg one asserted
fields that no longer exist, so the crate did not compile in any test
build.

Assert what exists: `queued_jobs` after submit, `queue_nonempty` true
while the surviving front job is ready and false once the run is drained,
with the front labels still asserted in the global dispatch order (the
point of the index).

The Postgres malformed-`runs_on` case now pins the *gauge* contract
directly (`ready_front_labels` returns no labels instead of failing): the
cancel command also runs the promotion sweep, which scans the ready set for
admission, and tolerating a non-list `runs_on` there is a scheduling
decision this change does not make — the lite twin keeps covering the
command path end to end.
The rust-lint job runs `cargo fmt --all -- --check`; the new gauge tests and
the migration const list landed unformatted.
@Bnjoroge1
Bnjoroge1 force-pushed the Bnjoroge/queue-gauges branch from 8b4d963 to df57951 Compare October 7, 2026 15:02
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