Skip to content

[v8] Use embedded process instances for "cf apps" summary#3725

Open
jochenehret wants to merge 3 commits intocloudfoundry:v8from
sap-contributions:v8_apps_cmd_process_instances
Open

[v8] Use embedded process instances for "cf apps" summary#3725
jochenehret wants to merge 3 commits intocloudfoundry:v8from
sap-contributions:v8_apps_cmd_process_instances

Conversation

@jochenehret
Copy link
Contributor

Description of the Change

Use the new "embedded process instances" cloud controller feature to speed up the cf apps command, in particular on spaces with a larger number of apps. Instead of calling the individual /stats endpoint per process, use this request once per space:
GET /v3/processes?space_guids=:guid&embed=process_instances

Why Is This PR Valuable?

Time comparison on a test space with 100 apps and 2 instances each:

# old implementation
cf apps  0.18s user 0.07s system 1% cpu 12.572 total

# new implementation
cf apps  0.07s user 0.03s system 6% cpu 1.453 total

Applicable Issues

cloudfoundry/cloud_controller_ng#4796

How Urgent Is The Change?

Not super-urgent.

* use "/v3/processes?space_guids=:guid&embed=process_instances" to get processes and process instances in one request
* see cloudfoundry/cloud_controller_ng#4796
@jochenehret jochenehret force-pushed the v8_apps_cmd_process_instances branch from c4b3d1c to dea08a9 Compare February 23, 2026 10:42
@jochenehret jochenehret marked this pull request as ready for review February 23, 2026 10:50
@jochenehret jochenehret changed the title Use embedded process instances for "cf apps" summary [v8] Use embedded process instances for "cf apps" summary Feb 23, 2026
@jochenehret jochenehret marked this pull request as draft February 23, 2026 13:44
@jochenehret
Copy link
Contributor Author

@jochenehret jochenehret marked this pull request as ready for review March 4, 2026 13:31
@jochenehret
Copy link
Contributor Author

Integration test is still failing. It should succeed once https://github.com/cloudfoundry/capi-release/releases/tag/1.229.0 is used (last run was with 1.228.0).

var instanceDetails []ProcessInstance
if process.EmbeddedProcessInstances != nil {
for _, instance := range *process.EmbeddedProcessInstances {
instanceDetails = append(instanceDetails, NewProcessInstance(instance.Index, constant.ProcessInstanceState(instance.State), time.Duration(instance.Since)))
Copy link
Contributor

Choose a reason for hiding this comment

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

time.Duration(instance.Since) treats Since (an integer of seconds) as nanoseconds, not seconds. time.Duration's base unit is nanoseconds, so time.Duration(300) = 300ns, not 300s.

For comparison, the existing /stats endpoint unmarshal in process_instance.go correctly converts seconds via:

instance.Uptime, err = time.ParseDuration(fmt.Sprintf("%ds", inputInstance.Uptime))

This means uptime values from the new path will be off by a factor of 10⁹, which will display effectively as zero uptime for all instances.

Fix:

instanceDetails = append(instanceDetails, NewProcessInstance(
    instance.Index,
    constant.ProcessInstanceState(instance.State),
    time.Duration(instance.Since) * time.Second,
))

The test expectations (e.g. Uptime: 300) also need updating to Uptime: 300 * time.Second to match the corrected behavior and the existing /stats code path.

DiskInMB types.NullUint64
LogRateLimitInBPS types.NullInt
AppGUID string
EmbeddedProcessInstances *[]EmbeddedProcessInstance
Copy link
Contributor

Choose a reason for hiding this comment

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

(nit - feel free to ignore)

Using *[]EmbeddedProcessInstance (pointer to slice) is unusual in Go — a nil slice already distinguishes "not present" from "present but empty". Consider whether []EmbeddedProcessInstance with omitempty (I think you already have this) on the JSON tag achieves the same semantics more idiomatically.

If the intent is to distinguish between "field absent from JSON" and "field present as []", then the pointer-to-slice is correct. But if that distinction isn't needed, a plain slice would be simpler and avoid the dereference (*process.EmbeddedProcessInstances) in consuming code.

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