fix(control-plane): give the fake tenant registry KV's last-writer-wins installation index - #9630
Conversation
…ns installation index
createFakeTenantRegistry answered getByOrbInstallationId with a linear
scan of its records Map in insertion order (first-inserted-wins), while
createKvTenantRegistry resolves through its installation:${id}
secondary index (last-writer-wins with JSONbored#9143's compare-and-delete
rule). For the duplicated-installation scenario JSONbored#9143 documents as real
-- a failed tenant's claim taken over by a new active tenant -- the two
implementations returned OPPOSITE tenants, so http-app.test.ts (which
injects the fake) asserted inverted webhook-routing and
installation_already_claimed 409 semantics.
Give the fake its own in-memory Map<number, string> installation ->
primary-key index, maintained on every upsert exactly like the KV
path: last writer wins, stale pointers removed on a cleared/changed
claim only when they still point at the upserting record's own key.
upsert/get/list are otherwise unchanged, including list()'s sort, and
the header comment now describes the index instead of a linear scan.
Closes JSONbored#9613
|
Warning ⏸️ LoopOver review result - manual review recommendedReview updated: 2026-07-29 01:54:23 UTC
Review summary Nits — 4 non-blocking
Decision drivers
Context & advisory signals — never blocks the verdict
Linked issue satisfactionAddressed Review context
Contributor next steps
Signal definitions
🧪 Chat with LoopOverAsk LoopOver a question about this PR directly in a comment — grounded only in the same cached, public-safe facts shown above, never a new claim.
Full command reference: https://loopover.ai/docs/loopover-commands 🧪 Experimental — new and may change. 🟩 Safe / merged · 🟦 Advisory · 🟨 Held for review · 🟥 Blocked / closed 💰 Earn for open-source contributions like this. Gittensor lets GitHub contributors earn for the work they already do — register to start earning →. Checked by LoopOver, a quiet PR intelligence layer for OSS maintainers.
|
|
Superagent didn't find any vulnerabilities or security issues in this PR. |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #9630 +/- ##
==========================================
- Coverage 90.08% 89.26% -0.83%
==========================================
Files 889 889
Lines 112024 112041 +17
Branches 26587 26590 +3
==========================================
- Hits 100921 100014 -907
- Misses 9773 10939 +1166
+ Partials 1330 1088 -242
Flags with carried forward coverage won't be shown. Click here to find out more.
|
Closes #9613
Summary
fix(control-plane): give the fake tenant registry KV's last-writer-wins installation indexcreateFakeTenantRegistry.getByOrbInstallationIdwas[...records.values()].find(...)— a linear scan inMapinsertion order, i.e. first-inserted-wins — whilecreateKvTenantRegistryresolves through itsinstallation:${id}secondary index, whichupsertrepoints on every write: last-writer-wins, with #9143's compare-and-delete rule. The two implementations agree only while at most one record carries a given installation ID, and the #9143 comment block in this same file documents that assumption as false by design (isRecreatableStatelets a failed/torn-down tenant's claim be taken over by a new tenant). For that exact scenario the fake resolved555to the stale"old"tenant while KV resolves it to"newcomer"— and the fake is whathttp-app.test.tsinjects, so theinstallation_already_claimed409 and webhook-routing assertions ran against inverted semantics.Root cause
The fake derived the answer by scanning
recordsat read time instead of maintaining the write-time installation index the real implementation's semantics come from.Fix
installationIndex: Map<number, string>(installation → primary key) inside the closure, maintained on everyupsertexactly likecreateKvTenantRegistry's index maintenance: the new claim always repoints the index (last writer wins), and a cleared/changed claim removes the stale entry only if it still points at the upserting record's own key (control-plane: eight pre-deploy defects, headlined by two tenants sharing one Neon database (and one customer's teardown deleting another's) #9143's compare-and-delete — a late upsert of a stale record can never rip out another tenant's live pointer).getByOrbInstallationIdresolves through the index; no scan.upsert,get, andlistotherwise unchanged, includinglist()'s existing sort.TenantRegistryinterface,createKvTenantRegistry, andhttp-app.tsuntouched.Diff:
control-plane/src/tenant-registry.ts(+27/−5) andcontrol-plane/test/tenant-registry.test.ts(+42) only.Tests (RED → GREEN)
Against the unfixed source, the required named regression test fails (the fake resolves the duplicated ID to the stale
"old"tenant):After the fix:
("old","orb","failed")withorbInstallationId: 555, then("newcomer","orb","active")with555→getByOrbInstallationId(555)resolves to"newcomer"; then upsert("old","orb","torn down")with noorbInstallationId→ still"newcomer"(compare-and-delete keeps the pointer).555 → 777returnsundefinedfor555and the tenant for777(mirrors the existing KV test), plus a same-ID re-upsert leaves the pointer in place (the unchanged-claim arm)."getByOrbInstallationId finds a tenant by installation ID, undefined for an unclaimed one") passes unmodified, as does the whole pre-existing suite.Coverage
Control-plane files are graded by the
control-planeCodecov flag; I ran CI's exact recipe (node --experimental-strip-types scripts/control-plane-coverage.ts, c8 over the built dist remapped tocontrol-plane/src/**):Cross-referencing the lcov against this PR's diff hunks:
control-plane/src/tenant-registry.ts— changed lines 22, uncovered changed lines none, partial branches on changed lines none; whole file has zero uncovered lines or branches. Both arms of every new conditional are exercised: upsert with an ID / without / changed / unchanged, and the compare-and-delete branch in both the "index still points at me" (delete) and "index points at someone else" (keep) cases.Validation commands (repo root)