Skip to content

perf(cloudfoundry): skip dead per-space enrichment on prewarm drain - #5614

Merged
norman-abramovitz merged 2 commits into
cloudfoundry:developfrom
nabramovitz:norm/fix/stratos-space-drain-skip-dead-enrichment
Jul 10, 2026
Merged

perf(cloudfoundry): skip dead per-space enrichment on prewarm drain#5614
norman-abramovitz merged 2 commits into
cloudfoundry:developfrom
nabramovitz:norm/fix/stratos-space-drain-skip-dead-enrichment

Conversation

@nabramovitz

Copy link
Copy Markdown
Contributor

Problem

EndpointDataService prewarms a hot cache by draining the whole space list (loadSpaces / refreshSpacesdrainCfPages('/pp/v1/cf/spaces/{cnsi}')). That hits getNativeSpaces, whose default path enriches every returned space with app and route counts via fetchAppCountsForSpaces / fetchRouteCountsForSpaces — chunked, sequential filtered CAPI round-trips, ~8 per page.

Nothing displays those per-space counts off the all-spaces list. Every consumer of EndpointDataService.spaces() (routes / users / audit-events / space-roles resolvers, add-edit-space) reads only name + guid. The counts shown on the org→spaces tab come from a different handler, getNativeOrgSpaces, which is untouched here. So the prewarm enrichment is computed and discarded.

On a large foundation the enrichment dominates the drain cost and, fanned out across the prewarm's pages, saturates the jetstream→CF proxy path.

Fix

  • Backend: getNativeSpaces honors ?enrich=none, routing through the existing skip branch so no count fetches are issued. Default requests and getNativeOrgSpaces are unchanged.
  • Frontend: drainCfPages gains an extraParams argument; the two prewarm drains pass enrich=none. Only the speculative space prewarm is affected — orgs/apps drains are untouched.

Measurement

Foundation with 2511 spaces but only 54 apps / 54 routes (so the counts are cheap for CF to compute — the cost is the serial round-trips, not CF):

Request Time Result
default (with enrich) 5.3–5.8s 500 spaces
?enrich=none 1.75–1.85s 500 spaces (identical guid/name/org data)

Raw cf curl /v3/spaces?per_page=500 is ~1.5s, so enrich=none is at the CF floor.

Tests

Adds TestGetNativeSpaces_EnrichNoneSkipsCounts — asserts enrich=none skips app/route enrichment with no guids filter present while still returning the full space list. Full plugins/cloudfoundry package passes.

The EndpointDataService prewarm drains the whole space list purely as a
guid->name catalog (routes/users/audit-events resolvers read only name
and guid). getNativeSpaces was enriching every returned space with app
and route counts that nothing displays off this list; the counts shown
on the org->spaces tab come from getNativeOrgSpaces instead. On large
foundations that enrichment is ~8 sequential filtered CAPI round-trips
per page and dominates the drain cost.

Add ?enrich=none to getNativeSpaces (reusing the existing skip branch)
and have the prewarm drains (loadSpaces, refreshSpaces) pass it via a
new drainCfPages extraParams argument. Default requests and
getNativeOrgSpaces are unchanged.

Measured on a 2511-space foundation: page fetch 5.5s -> 1.8s, same 500
spaces returned.
The perf change appends enrich=none to the two spaces-drain requests,
but SPACES_FULL_URL still matched the un-enriched URL, so every
expectOne(SPACES_FULL_URL) left the real request open — httpMock.verify()
then threw in afterEach and cascaded across the suite (44/50 failed).
Align the constant with the request the drain now makes.
@nabramovitz
nabramovitz force-pushed the norm/fix/stratos-space-drain-skip-dead-enrichment branch from a34bd9f to 1eb044b Compare July 10, 2026 11:59

@norman-abramovitz norman-abramovitz left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@norman-abramovitz
norman-abramovitz merged commit 0e66109 into cloudfoundry:develop Jul 10, 2026
21 checks passed
@nabramovitz
nabramovitz deleted the norm/fix/stratos-space-drain-skip-dead-enrichment branch July 24, 2026 12:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants