fix(routing): skip known-exhausted accounts at admission#57
Conversation
There was a problem hiding this comment.
All reported issues were addressed across 10 files
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
d5f1fdd to
8dfde55
Compare
|
Thanks. The candidate-loop replay safety work is useful, but this stacked branch needs revision before merge:
Please rerun the full gate on the rebased branch. |
c03687c to
15d11bb
Compare
|
Thanks for the revision. The clean rebase, main/sidebar identity handling, reset expiry, both-window evaluation, and production-selector coverage are now in place. One blocker remains: fallback quota is not identity-bound across re-login. Bind fallback cached and persisted quota to the stable fallback identity, then add production-loader regressions for fallback re-login identity isolation and secondary-only admission exhaustion. |
15d11bb to
e8fe6d5
Compare
Why
Rate-limit marks are per-process and in-memory. With several concurrent opencode processes and
fallback-firstrouting pinned at an exhausted account, every process independently pays one doomed admission probe (admission-timeusage_limit_reached→ mark → retryable error → reroute) before learning what the machine-global sidebar file already knows: the account is at 100% with a reset days away. The operator sees each discovery as a visible retry/error flash.What
Admission-time candidate selection now consults quota before probing:
primary.checkedAt, then snapshotcheckedAt, then entrycheckedAt). The fresher source is selected — the file wins only when strictly newer, memory wins ties, and an empty in-memory cache (fresh process) defers to a valid file row.isQuotaExhausted(type-safe, fail-open) is applied only to the selected source.fallback-first) gate and the reactive iterator via a shared memoized selection.quota-exhausted,Retry-Afterfrom the account's ownresetsAt) so the reroute happens without the doomed probe — only when a non-exhausted fallback survives.admission skip: exhausted account {accountId, source, resetsAt}.Verification
client-alt, gotwork-alt), fresh-process file exhaustion, newer-exhausted-file vs stale-healthy-memory, exhausted primary reroute — all fail pre-fix; 7 fail-open characterizations proven non-vacuous by reverse-applying the src diff (they pass on reverted source, i.e. they pin non-interference).Need help on this PR? Tag
/codesmithwith what you need. Autofix is disabled.Summary by cubic
Skip probes for accounts already known to be quota‑exhausted by consulting the freshest, identity‑matched quota from memory or the shared sidebar. When main is exhausted and a healthy fallback exists, short‑circuit with a precise 429 using the earliest exhausted window reset.
New Features
getSidebarState, once per request), require identity match (ignore mismatchedmainAccountId/fallbackaccountId), drop exhausted candidates, reuse the same selection for proactive/reactive paths; log skips; if filtering would remove the last path, keep the original probe order.quota-exhausted) withRetry-Afterfrom the earliest exhausted window’sresetsAt; only when a non‑exhausted fallback survives.QuotaManager(peekFallbackForPolicy(id, identity?)drops on mismatch;setFallbackand seeding carry identity). Sidebar/state includes window/snapshotcheckedAt,mainAccountId, and per‑fallbackaccountId, and merges by freshness per account with identity tied to the winning snapshot.Bug Fixes
setSidebarMachineState; single tolerant sidebar read per request.Written for commit e8fe6d5. Summary will update on new commits.