The bundle index serves from live listings
Systemorph/MeshWeaver#7354.
Every installation polls its registry's bundle index (GET /api/plugins/bundles/index.json) to
learn which packages and module builds it may adopt. The handler assembled that answer by running
two IMeshService.Query listings on every request and waiting for each one's Initial:
| listing | query | what it contributes |
|---|---|---|
| install records | namespace:Plugins nodeType:Package |
the packages this registry installed |
| partition registry | namespace:Admin/Partition nodeType:Partition |
whether an anchored package's content is held here |
Measured from inside two production portals: the index — an 8.7 KB document — connected in about 0.03 s and took 12 to 19 s to first byte. The cost was a fan-in query per poll per consumer, so it grew with the fleet and with the number of published packages. A query is the CQRS read side, for listings whose stale answer is harmless; assembling a hot response from a fresh one on every call is the misuse the platform's data-access rules name.
What it does now
PluginBundleIndexSources (src/Memex.Portal.Shared/Api) is a mesh-scoped singleton
(MeshBuilder.AddPluginBundleIndex(), registered by the portal's mesh configuration). For each of
the two listings it holds ONE standing subscription, opened as System on the first index request,
and folds its change feed into the current set:
Initial/Resetreplace the set;Added/Updatedset an entry;Removeddrops one.
An index request takes the current set — or waits for the first complete listing if none has arrived yet. An install, an uninstall or a new partition reaches the next index through the feed itself: no poll, no timer, no re-query.
Faults
A listing whose feed faults hands the fault to every request waiting on it and is dropped; the next request opens a fresh one. So:
- a stalled read still answers 503 + Retry-After (
PluginBundleStalledReadTest), and an ordinary defect still escapes as one — exactly as the per-request query did; - nothing re-opens on a timer, and no fault is replayed to a request that arrives after it (a
replayed
OnErroris the latched-fault trap of #1369).
The index's answer deadline (RegistryAnswerDeadline) is unchanged and still names the stage a
request was waiting on: installed packages (install records) or
held partitions (partition registry).
What still queries per request
The download route (GET …/{plugin}/{version}) keeps a fresh listing per fetch, on purpose. It
decides which bytes a consumer lands, so — like its authoritative module-activation read — it must
see an install another replica wrote a moment ago, and it runs once per actual fetch rather than once
per poll.
Evidence
Memex.Portal.Shared.Test → TheBundleIndexRunsNoQueryPerPollTest: a test query provider joins the
fan-in beside the real store and counts install-record listings. Three polls open one (the
per-request shape opened three), and a package installed after the first poll is listed by a later
poll with no further listing opened.