fix: forward resample algorithm to metric store for running jobs

Only archived job data and internal-store node-list data honoured the
selected resample algorithm. For running jobs the algorithm was dropped:
MetricDataRepository.LoadData had no such parameter, so the memory store
fell back to an empty string, which cc-lib's GetResampler maps to LTTB.
The external store client was worse - its APIQueryRequest had no
ResampleAlgo field at all, and LoadNodeListData accepted the parameter
without using it.

Add resampleAlgo to the LoadData interface (mirroring LoadNodeListData),
forward it from metricdispatch, and set it on both stores' requests. The
field is tagged omitempty, so the wire format is unchanged when empty -
verify the deployed cc-metric-store accepts it before relying on it there.

The REST job endpoints pass a non-zero resolution and therefore do
resample, so they now request the configured default instead of an empty
string. Add config.ResampleAlgo() for that, since "" is not a neutral
value at this layer.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-08-27 12:17:03 +02:00
co-authored by Claude Opus 5
parent d40390061d
commit a5c1fdf21f
8 changed files with 59 additions and 36 deletions
+23 -19
View File
@@ -81,13 +81,14 @@ type CCMetricStore struct {
// APIQueryRequest represents a request to the cc-metric-store query API.
// It supports both explicit queries and "for-all-nodes" bulk queries.
type APIQueryRequest struct {
Cluster string `json:"cluster"` // Target cluster name
Queries []APIQuery `json:"queries"` // Explicit list of metric queries
ForAllNodes []string `json:"for-all-nodes"` // Metrics to query for all nodes
From int64 `json:"from"` // Start time (Unix timestamp)
To int64 `json:"to"` // End time (Unix timestamp)
WithStats bool `json:"with-stats"` // Include min/avg/max statistics
WithData bool `json:"with-data"` // Include time series data points
Cluster string `json:"cluster"` // Target cluster name
Queries []APIQuery `json:"queries"` // Explicit list of metric queries
ForAllNodes []string `json:"for-all-nodes"` // Metrics to query for all nodes
From int64 `json:"from"` // Start time (Unix timestamp)
To int64 `json:"to"` // End time (Unix timestamp)
WithStats bool `json:"with-stats"` // Include min/avg/max statistics
WithData bool `json:"with-data"` // Include time series data points
ResampleAlgo string `json:"resample-algo,omitempty"` // Downsampling algorithm ("lttb", "average", "simple"); empty = server default
}
// APIQuery specifies a single metric query with optional scope filtering.
@@ -231,6 +232,7 @@ func (ccms *CCMetricStore) LoadData(
scopes []schema.MetricScope,
ctx context.Context,
resolution int,
resampleAlgo string,
) (schema.JobData, error) {
queries, assignedScope, err := ccms.buildQueries(job, metrics, scopes, resolution)
if err != nil {
@@ -245,12 +247,13 @@ func (ccms *CCMetricStore) LoadData(
}
req := APIQueryRequest{
Cluster: job.Cluster,
From: job.StartTime,
To: job.StartTime + int64(job.Duration),
Queries: queries,
WithStats: true,
WithData: true,
Cluster: job.Cluster,
From: job.StartTime,
To: job.StartTime + int64(job.Duration),
Queries: queries,
WithStats: true,
WithData: true,
ResampleAlgo: resampleAlgo,
}
resBody, err := ccms.doRequest(ctx, &req)
@@ -632,12 +635,13 @@ func (ccms *CCMetricStore) LoadNodeListData(
}
req := APIQueryRequest{
Cluster: cluster,
Queries: queries,
From: from.Unix(),
To: to.Unix(),
WithStats: true,
WithData: true,
Cluster: cluster,
Queries: queries,
From: from.Unix(),
To: to.Unix(),
WithStats: true,
WithData: true,
ResampleAlgo: resampleAlgo,
}
resBody, err := ccms.doRequest(ctx, &req)