[Bug] Fix external metric fetching for GPU optimizer autoscaling and replace dead scale-down annotation in samples - #2616
Conversation
…ation with autoscaling.aibrix.ai/scale-down-cooldown-window in all sample manifests Signed-off-by: Alex Jia <yj2761@nyu.edu>
…int and path instead of the central metric registry, and switch samples from the deprecated domain source type to external Signed-off-by: Alex Jia <yj2761@nyu.edu>
There was a problem hiding this comment.
Code Review
This pull request renames the scale-down delay annotation to autoscaling.aibrix.ai/scale-down-cooldown-window and updates the metric source type from domain to external across various YAML configurations. Additionally, it introduces a FetchRawMetric method in the metrics engine fetcher to retrieve raw Prometheus metrics directly from configured endpoints, bypassing the central registry. Feedback on these changes highlights two improvement opportunities in FetchRawMetric: replacing time.After with time.NewTimer to prevent potential memory leaks upon context cancellation, and checking ctx.Err() after a failed fetch to fail fast when the context is cancelled.
| select { | ||
| case <-ctx.Done(): | ||
| return nil, ctx.Err() | ||
| case <-time.After(delay): | ||
| } |
There was a problem hiding this comment.
Using time.After in a select statement inside a loop can cause a temporary memory leak if the context is cancelled before the timer fires, as the underlying timer is not stopped and remains in memory until it expires. It is highly recommended to use time.NewTimer instead and ensure it is stopped when the select block exits.
timer := time.NewTimer(delay)
select {
case <-ctx.Done():
timer.Stop()
return nil, ctx.Err()
case <-timer.C:
}There was a problem hiding this comment.
plz check this to avoid memory leak
There was a problem hiding this comment.
plz check this to avoid memory leak
done
| allMetrics, err := ef.fetchAllMetricsFromURL(ctx, url) | ||
| if err != nil { | ||
| klog.V(4).InfoS("Failed to fetch metrics from URL", | ||
| "attempt", attempt+1, "identifier", identifier, "url", url, "error", err) | ||
| continue | ||
| } |
There was a problem hiding this comment.
If fetchAllMetricsFromURL fails because the context was cancelled or timed out, continuing the loop will log a misleading retry message and wait unnecessarily. Checking ctx.Err() immediately after the error allows the function to fail fast and return the context error without redundant logging or retries.
allMetrics, err := ef.fetchAllMetricsFromURL(ctx, url)
if err != nil {
if ctx.Err() != nil {
return nil, ctx.Err()
}
klog.V(4).InfoS("Failed to fetch metrics from URL",
"attempt", attempt+1, "identifier", identifier, "url", url, "error", err)
continue
}There was a problem hiding this comment.
Pull request overview
This PR fixes optimizer-based autoscaling samples by (1) updating a deprecated/ignored scale-down annotation to the currently supported key and (2) restoring external metric fetching from the GPU optimizer by honoring the configured path and bypassing the central engine-metric registry for optimizer-provided metrics.
Changes:
- Replace
kpa.autoscaling.aibrix.ai/scale-down-delaywithautoscaling.aibrix.ai/scale-down-cooldown-windowacross affected sample/config YAMLs. - Add
EngineMetricsFetcher.FetchRawMetricto fetch a raw Prometheus metric from an explicit URL (no central registry lookup). - Update the GPU optimizer external-metrics fetch path to build
protocol://endpoint/<path>and useFetchRawMetric; add unit tests for the new behavior.
Reviewed changes
Copilot reviewed 17 out of 17 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| samples/volcano-engine/autoscaler.yaml | Updates scale-down annotation key to the supported one. |
| samples/heterogeneous/deepseek-coder-7b-v100-podautoscaler.yaml | Updates annotation key; switches metricSourceType to external. |
| samples/heterogeneous/deepseek-coder-7b-l20-podautoscaler.yaml | Updates annotation key; switches metricSourceType to external. |
| samples/deepseek-r1/deepseek-r1-autoscaling.yaml | Updates scale-down annotation key to the supported one. |
| samples/autoscaling/optimizer-kpa.yaml | Updates annotation key; switches metricSourceType to external. |
| samples/autoscaling/kpa.yaml | Updates scale-down annotation key to the supported one. |
| samples/autoscaling/external-metrics-kpa.yaml | Updates scale-down annotation key to the supported one. |
| pkg/metrics/engine_fetcher.go | Adds FetchRawMetric for unregistered/external Prometheus metric fetching from an explicit URL. |
| pkg/metrics/engine_fetcher_test.go | Adds unit tests covering FetchRawMetric success and failure modes. |
| pkg/controller/podautoscaler/metrics/fetcher.go | Builds optimizer URL from protocolType, endpoint, path and uses FetchRawMetric. |
| development/tutorials/distributed/fleet-autoscaling.yaml | Updates scale-down annotation key to the supported one. |
| development/app/config/templates/podautoscaler/podautoscaler_kpa.yaml | Updates scale-down annotation key to the supported one. |
| development/app/config/simulator/patch_podautoscaler_a100.yaml | Updates annotation key; switches metricSourceType to external. |
| development/app/config/heterogeneous/simulator_a40/patch_podautoscaler_a40.yaml | Updates annotation key; switches metricSourceType to external. |
| config/samples/autoscaling_v1alpha1_mock_llama.yaml | Updates scale-down annotation key to the supported one. |
| benchmarks/scenarios/autoscaling/deepseek-llm-7b-chat/optimizer-kpa.yaml | Updates annotation key; switches metricSourceType to external. |
| benchmarks/scenarios/autoscaling/deepseek-llm-7b-chat/kpa.yaml | Updates scale-down annotation key to the supported one. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| allMetrics, err := ef.fetchAllMetricsFromURL(ctx, url) | ||
| if err != nil { | ||
| klog.V(4).InfoS("Failed to fetch metrics from URL", | ||
| "attempt", attempt+1, "identifier", identifier, "url", url, "error", err) | ||
| continue | ||
| } |
|
Here are a few findings and structural observations from reviewing the new 1. Robustness & Error Handling
2. Metric & Protocol Support
3. Maintainability
|
…ng a pending time.After timer behind Signed-off-by: Alex Jia <yj2761@nyu.edu>
…s_query_fail engine counter Signed-off-by: Alex Jia <yj2761@nyu.edu>
Pull Request Description
This PR fixes two bugs that make
samples/autoscaling/optimizer-kpa.yaml(and the heterogeneous GPU samples that copy it) not work. If you apply these samples today, the PodAutoscaler starts up but fails to read its metric on every cycle, so it never scales anything.Bug 1: the annotation does nothing. The samples set
kpa.autoscaling.aibrix.ai/scale-down-delay, but the controller no longer reads keys with thekpa.prefix. It only readsautoscaling.aibrix.ai/scale-down-cooldown-window. The old key is silently ignored, so scale-down always waits the default 5 minutes. This PR renames the key to the correct one in all 14 files that had it, keeping each file's original value.Bug 2: the metric can never be fetched. These samples read
vllm:deployment_replicasfrom the GPU optimizer. This worked when the samples were written, but the metrics fetcher refactor (#1487) changed how external metrics are fetched, and two things broke:pathfield and always calls/metrics, but the GPU optimizer only serves/metrics/{namespace}/{deployment}.The fix:
FetchRawMetric, that fetches a metric straight from the given URL without checking the registry. External metrics like the optimizer's output are not engine metrics, so the registry should not apply to them.protocolType,endpoint, andpathfields in the spec, sopathis actually used.metricSourceType: externalinstead of the deprecateddomain.Testing: a new unit test covers the new method (fetching an unregistered metric from an optimizer-style path, a metric missing from the response, and a wrong path). All existing unit tests for
pkg/metricsandpkg/controller/podautoscalerpass, along withgo build,go vet, andgofmt.Related Issues
Resolves: #2615
Important: Before submitting, please complete the description above and review the checklist below.
Contribution Guidelines (Expand for Details)
We appreciate your contribution to aibrix! To ensure a smooth review process and maintain high code quality, please adhere to the following guidelines:
Pull Request Title Format
Your PR title should start with one of these prefixes to indicate the nature of the change:
[Bug]: Corrections to existing functionality[CI]: Changes to build process or CI pipeline[Docs]: Updates or additions to documentation[API]: Modifications to aibrix's API or interface[CLI]: Changes or additions to the Command Line Interface[Misc]: For changes not covered above (use sparingly)Note: For changes spanning multiple categories, use multiple prefixes in order of importance.
Submission Checklist
By submitting this PR, you confirm that you've read these guidelines and your changes align with the project's contribution standards.