Repository navigation
fix(db): stop backoff-reset from busting the model catalog cache (#13389) - #13783
Merged
diegosouzapw merged 2 commits intoSep 16, 2026
Merged
Conversation
) resetConnectionBackoff() ran through invalidateDbCache("connections"), which unconditionally bumps modelCatalogCacheVersion and clears the entire /v1/models response cache — even though the catalog builder (src/app/api/v1/models/catalog.ts) never reads backoff/error/cooldown state, only structural fields (excludedModels, enabled/disabled, etc). Since resetConnectionBackoff fires automatically on every routine connection auto-recovery during request routing (src/sse/services/auth.ts), this was busting the catalog cache far more often than its 60s TTL / 30s stale-while-revalidate window intends, forcing frequent expensive cold rebuilds — the dominant trigger behind the reported 75-120s/502 spread. Adds a `skipModelCatalog` option to invalidateDbCache and passes it only from resetConnectionBackoff; every other "connections" call site in providers.ts (create/update/dedupe-merge) is structural and keeps the default full invalidation. Regression test: tests/unit/issue-13389-catalog-cache-backoff-reset.test.ts Does not cover the should-fix half of #13389 (the CATALOG_BUILD_TIMEOUT_MS abort not bounding a genuinely slow-but-not-hung synchronous builder) — tracked as a separate follow-up.
…120s (base-red fix #13747)
muhamadgalihsaputra
pushed a commit
to niyatna/NiyatnaRoute
that referenced
this pull request
Sep 27, 2026
…gosouzapw#13389) (diegosouzapw#13783) Merged in the 2026-09-16 sweep of the maintainer's own open PRs, at the owner's explicit instruction. No push was made to the PR branch: the merge took the head as the owning session left it (verified OPEN, non-draft and MERGEABLE against the release tip immediately before merging).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Refs #13389
Not covered here (follow-up,
Refs #13389):CATALOG_BUILD_TIMEOUT_MSfor a genuinelyslow-but-not-hung synchronous builder (currently only a never-resolving/hung builder is
bounded). This is a materially larger change (worker-thread offload or finer-grained
SQLite yield points) and is tracked as a separate follow-up.
Root cause (short)
resetConnectionBackoff()(src/lib/db/providers.ts) fires automatically whenever apreviously-cooled-down connection is auto-recovered during normal request routing
(
src/sse/services/auth.ts). It calledinvalidateDbCache("connections"), whichunconditionally bumps
modelCatalogCacheVersion— busting the entire/v1/modelsresponse cache as a side effect, even though the catalog builder
(
src/app/api/v1/models/catalog.ts) never reads backoff/error/cooldown state at all(
backoffLevel,testStatus,rateLimitedUntil,lastError*,errorCode) — onlystructural fields such as
excludedModelsor enabled/disabled.On a deployment routing many providers, this invalidated the catalog cache far more often
than its 60s TTL / 30s stale-while-revalidate window intends, purely as a side effect of
unrelated chat traffic, forcing frequent expensive cold rebuilds — the dominant trigger
behind the reported 75-120s/502 spread (independent of the 8s cold-build timeout added in
#12628, which itself only bounds a hung build, not a slow one — see the follow-up above).
Fix
Added a
skipModelCatalogoption toinvalidateDbCache()(src/lib/db/readCache.ts).resetConnectionBackoffnow passes it, so it still busts the connections read cache(needed for accurate routing) but no longer bumps
modelCatalogCacheVersion.Audited every other
invalidateDbCache("connections", …)call site inproviders.ts(create, dedupe-merge update, general update) — all are structural connection writes that
genuinely change catalog-relevant fields, so they keep the default full invalidation.
Regression test (path + RED output excerpt on unfixed code + GREEN excerpt)
tests/unit/issue-13389-catalog-cache-backoff-reset.test.tsRED (unfixed code):
GREEN (fixed code):
Gates run
npx eslint --suppressions-location config/quality/eslint-suppressions.json src/lib/db/providers.ts src/lib/db/readCache.ts tests/unit/issue-13389-catalog-cache-backoff-reset.test.ts→ clean, exit 0npm run typecheck:core→ clean, exit 0node scripts/check/check-file-size.mjs→ clean (trimmed the added comment to keepproviders.tsat 1198 lines, under the frozen 1200-line cap)node scripts/check/check-complexity.mjs→ no violations for the touched filesnode scripts/check/check-cognitive-complexity.mjs→ no violations for the touched filesnode scripts/check/check-test-discovery.mjs→ OK, new test file discoveredtests/unit/reset-connection-backoff.test.ts,tests/unit/db-read-cache.test.ts) → 14/14 pass, unchangedExisting tests aligned
None needed changing —
invalidateDbCache's newoptsparameter is additive/optional, and noexisting test called
resetConnectionBackoffwhile asserting onmodelCatalogCacheVersion.