perf(related-resources): parallelize workload and service discovery with errgroup#438
Open
DioCrafts wants to merge 1 commit intokite-org:mainfrom
Open
Conversation
…ith errgroup
discoveryWorkloads() listed Deployments, StatefulSets and DaemonSets
sequentially — total latency was the sum of all 3 API calls. These
calls are completely independent, so they now run in parallel via
errgroup.WithContext, reducing latency to the max of the 3 calls
(~50-66% improvement).
Similarly, GetRelatedResources() called discoverServices (I/O) and
discoverConfigs (CPU-only) sequentially. They are now parallelized
so the CPU work overlaps with the service list call.
Also replaced all `&client.ListOptions{Namespace: ns}` with the
idiomatic `client.InNamespace(ns)`, removing the now-unused
ListOptions struct construction pattern.
Changes:
- discoveryWorkloads: 3 sequential List → 3 parallel goroutines
- GetRelatedResources: discoverServices + discoverConfigs → parallel
- All List calls use client.InNamespace() instead of &client.ListOptions{}
- errgroup.WithContext provides automatic cancellation on first error
- Zero shared mutable state between goroutines (each owns its list)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
⚡ perf(related-resources): Parallelize workload and service discovery with errgroup
Summary
The Related Resources panel — displayed every time a user clicks on a ConfigMap, Secret, PVC, Deployment, StatefulSet, DaemonSet, or Pod — was making up to 4 sequential Kubernetes API calls that are completely independent of each other. This PR rewrites both
discoveryWorkloads()and the service/config discovery block inGetRelatedResources()to execute all independent calls in parallel usingerrgroup, delivering ~50-66% faster response times on the most common resource detail views.Additionally, all
List()calls are migrated from the manual&client.ListOptions{Namespace: ns}pattern to the idiomaticclient.InNamespace(ns), improving code clarity.The Problem
1.
discoveryWorkloads()— 3 sequential API callsWhen a user views the related resources of a ConfigMap, Secret, or PersistentVolumeClaim, the code needs to find which workloads reference it. The original implementation listed all three workload types one after another:
None of these calls depend on each other. The DaemonSet list doesn't need the Deployment list, and vice versa. Running them sequentially wastes time waiting.
2.
GetRelatedResources()— sequential service + config discoveryWhen viewing related resources of a Deployment, StatefulSet, DaemonSet, or Pod, the code discovers related services (I/O call) and config references (CPU-only) sequentially:
The CPU work of
discoverConfigscould overlap entirely with the I/O call.3. Verbose
ListOptionsconstructionAll List calls used the manual pattern
&client.ListOptions{Namespace: namespace}instead of the idiomaticclient.InNamespace(namespace)helper provided by controller-runtime.The Solution
Parallel
discoveryWorkloads()with errgroup (Solution A)All 3 independent List calls now execute concurrently:
Key design decisions:
errgroup.WithContext()provides automatic cancellation — if one call fails, the others abort early instead of wasting resourcesg.Wait(), all results are safe to read without synchronizationParallel service + config discovery in
GetRelatedResources()(Solution B)Idiomatic
client.InNamespace()(Solution C)Performance Impact
discoveryWorkloads()— ConfigMap/Secret/PVC detail viewGetRelatedResources()— Deployment/StatefulSet/DaemonSet/Pod detail viewThe
discoverConfigsCPU work (~0.01ms) is now "free" — it runs while the service List I/O is in flight.User-visible impact
The Related Resources panel loads on every resource detail view in the Kite dashboard. Users opening a ConfigMap, Secret, Deployment, Pod, or any supported resource will see the related resources panel populate ~2-3x faster than before. This is especially noticeable in large namespaces with many workloads.
Concurrency Safety
g.Wait()provides a happens-before guaranteeerrgroup.WithContextcancels all goroutines on first errorgctxfrom errgroup ensures proper cancellation chainAPI Contract — Zero Breaking Changes
The JSON response of
GET /api/v1/resources/:namespace/:resourceType/:name/relatedis byte-for-byte identical. The only change is how fast the server computes it.What Changed
Added
golang.org/x/sync/errgroupimporterrgroup.WithContext()parallelization indiscoveryWorkloads()(3 goroutines)errgroup.WithContext()parallelization inGetRelatedResources()service+config block (2 goroutines)discoveryWorkloads()explaining the parallelizationChanged
&client.ListOptions{Namespace: ns}→client.InNamespace(ns)(4 call sites)Removed
discoveryWorkloads()(3 serial List + error checks)GetRelatedResources()(discoverServices + discoverConfigs)client.ListOptionsstruct construction (replaced by helper)Validation
go build ./...— Compiles cleanlygo vet ./pkg/handlers/resources/...— No issuesgo test ./pkg/handlers/... -count=1— 2/2 packages PASSerrgroup.WithContextensures proper cancellation propagationVisual Summary