Files
Jinwoo HongandClaude 7080eb0604 fix(relay): bound the idle-rehome candidate poll to a window of decisions (#21557)
* fix(relay): bound the idle-rehome candidate poll to a window of decisions

The director's idle-regional-rehome poll built every (eligible host x target
cell in its preferred region) pair, applied the cohort predicate downstream of
that fan-out, sorted the lot, and took LIMIT 100 OFFSET n. Its cost was set by
the size of the fleet and the width of the cohort, so raising the cohort from
10% to 100% pushed it past the serving pool's 5 s statement_timeout and the
rollout stalled at 0.37 hosts/min.

The poll now resolves the cell inventory once (tens of rows), takes a bounded
window of decision rows in primary-key order from a keyset cursor with the
cohort, freshness and cross-region predicates applied first, verifies only that
window against the host-side gates, and ranks targets in the process. Same
candidates in the same priority order; the work per poll no longer depends on
the cohort or the fleet.

Adds a once-a-minute aggregated poll summary so an operator can tell a poll
gated by the dispatch budget from one that found nobody to move.

Co-Authored-By: Claude <noreply@anthropic.com>

* fix(relay): pin the rehome verification to the window's exact keys

The window read and the verification read take separate snapshots. The
verification repeated the window's predicate with its own LIMIT, so a decision
that turned eligible between the two reads shifted that LIMIT and pushed the
window's last host out of it -- while the cursor still advanced past that host,
skipping it for a whole sweep.

The verification now names the keys the window returned. Its LIMIT stays as the
optimisation fence that stops Postgres flattening the subquery, but can no
longer truncate a key set that is at most one window long.

Co-Authored-By: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-09-18 21:16:19 -04:00
..