Uh oh!
There was an error while loading. Please reload this page.
perf(service-settings): getMany resolves same-namespace keys with one grouped row load (#10826) - #11200
Conversation
… grouped row load (#10826) resolveLocalizationContext (and getNamespace) called get() once per key, and every call ran loadRows over the whole namespace — three identical sys_setting reads inside one request (queries 16-18 of 24 on a live rig, PR #10824; already 1 leg since they run parallel, so per cloud#1539's calibration this is a query-count fix, not a latency fix, and the card is scheduled accordingly). getMany(namespace, keys, ctx): validate namespace + every key up front; resolve env overrides first (an override answers without touching the store, exactly as get() does); group the remaining keys by which loadRows argument their scope requires (user-scoped keys read (ns, userId), everything else (ns, null)); ONE load per group, both groups in parallel; walk each key's cascade over its group's rows. The cascade is EXTRACTED from get() into resolveKeyFromRows — shared, not copied — so per-key answers deep-equal get()'s by construction (pinned across env overrides, scope mixes, unknown-key refusal, and the read-count contract itself). getNamespace resolves through the same grouped path: N keys, <=2 loads. No caching; nothing survives the call. The resolve-authz-context caller switches to getMany in a follow-up on the #10825 branch (same-file serial ruling by the domain:engine seat). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
📓 Docs Drift CheckThis PR changes 1 package(s): 3 hand-written doc(s) NAME something this change touched and may need an implementation-accuracy re-verification:
What this run could not see
Coarse fallback — 7 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): Which tree this was computed onThis run read A worktree cut from an older # while this PR is open — GitHub drops the merge commit once it closes
git fetch origin d11ada336a135411033cf07a2f15a8f11d2a7703 && git checkout d11ada336a135411033cf07a2f15a8f11d2a7703
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin 18d5fec196de76c5054901521d01732f28e5128a 0ab67230169fcdf783e8dc4a133140c060ac99b5 && git checkout -B drift-repro 18d5fec196de76c5054901521d01732f28e5128a && git merge --no-ff 0ab67230169fcdf783e8dc4a133140c060ac99b5
node scripts/docs-audit/affected-docs.mjs --json 18d5fec196de76c5054901521d01732f28e5128a
|
Uh oh!
There was an error while loading. Please reload this page.
…ettings.getMany (objectstack-ai#10826) (objectstack-ai#11208) The caller half of objectstack-ai#10826 (service half: objectstack-ai#11200). One grouped namespace read replaces three per-key get()s — queries 16-18 of 24 on the measured rig collapse to one, with per-key answers unchanged by the service's equivalence contract. Feature-detected: an older service without getMany keeps the three parallel gets (still one leg — this is a query-count fix per the card's own calibration, not a latency fix). A thrown getMany lands exactly where a thrown get did: failed=true and the direct $in fallback, which reads the same three keys. Serial constraint honored: landed after objectstack-ai#11197 (objectstack-ai#10825) on this file. Co-authored-by: Jack Zhuang <277994282+os-zhuang@users.noreply.github.com> Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
What
SettingsService.getMany(namespace, keys, ctx): validate everything up front, resolve env overrides first (an override answers without touching the store, exactly asget()does), group the remaining keys by their scope'sloadRowsargument (user→(ns, userId), else(ns, null)), one load per group (both in parallel), and walk each key's cascade over its group's rows. The cascade is extracted fromget()into a sharedresolveKeyFromRows— not copied — so per-key answers deep-equalget()'s by construction.getNamespaceresolves through the same grouped path (N keys → ≤2 loads).Why (the card's own calibration honored)
resolveLocalizationContextissued three identicalsys_settingnamespace reads per request (queries 16–18/24, PR #10824's rig). They already ran parallel — 1 leg — so per cloud#1539 this is a query-count fix, not a latency fix, scheduled at the card's stated low priority as the same one-question-asked-repeatedly class as #10824's fixes. No caching; nothing survives the call (the #10221 failed-read TTL cache is untouched).Tests
New
settings-getmany.test.ts(6): per-key deep-equivalence withget()across scope mixes; read-count contract measured at the engine (same-scope → 1 find, mixed → 2, env-overridden → 0); unknown-key refusal parity;getNamespacethrough the grouped path with unchanged answers. Fullservice-settingssuite 477 passed, package tsc 0 errors.Serial note
The
resolve-authz-context.tscaller switches togetManyin a follow-up commit on the #10825 branch after it lands (same-file serial ruling by thedomain:engineseat — this PR touches onlyservice-settings).Part of #10826.
🤖 Generated with Claude Code