From 92180bc793e60c9aa5c33e4e146e8485db45ec9f Mon Sep 17 00:00:00 2001 From: Klaus Post Date: Wed, 21 Feb 2024 12:27:35 -0800 Subject: [PATCH] Add array recycling safety (#19103) Nil entries when recycling arrays. --- cmd/metrics-v2.go | 10 +++++----- cmd/peer-rest-server.go | 24 ++++++++++++++++-------- internal/grid/types.go | 4 +++- 3 files changed, 24 insertions(+), 14 deletions(-) diff --git a/cmd/metrics-v2.go b/cmd/metrics-v2.go index 971bfd4d9..f14fc2d0d 100644 --- a/cmd/metrics-v2.go +++ b/cmd/metrics-v2.go @@ -420,14 +420,14 @@ func (g *MetricsGroup) RegisterRead(read func(ctx context.Context) []Metric) { }) } -func (m *Metric) copyMetric() Metric { +func (m *Metric) clone() Metric { metric := Metric{ Description: m.Description, Value: m.Value, HistogramBucketLabel: m.HistogramBucketLabel, - StaticLabels: make(map[string]string), - VariableLabels: make(map[string]string), - Histogram: make(map[string]uint64), + StaticLabels: make(map[string]string, len(m.StaticLabels)), + VariableLabels: make(map[string]string, len(m.VariableLabels)), + Histogram: make(map[string]uint64, len(m.Histogram)), } for k, v := range m.StaticLabels { metric.StaticLabels[k] = v @@ -453,7 +453,7 @@ func (g *MetricsGroup) Get() (metrics []Metric) { metrics = make([]Metric, 0, len(m)) for i := range m { - metrics = append(metrics, m[i].copyMetric()) + metrics = append(metrics, m[i].clone()) } return metrics } diff --git a/cmd/peer-rest-server.go b/cmd/peer-rest-server.go index fb05f8b3e..6738d9237 100644 --- a/cmd/peer-rest-server.go +++ b/cmd/peer-rest-server.go @@ -1007,21 +1007,29 @@ func (s *peerRESTServer) GetBandwidth(params *grid.URLValues) (*bandwidth.Bucket // GetPeerMetrics gets the metrics to be federated across peers. func (s *peerRESTServer) GetPeerMetrics(_ *grid.MSS) (*grid.Array[*Metric], *grid.RemoteErr) { - m := ReportMetrics(context.Background(), peerMetricsGroups) - res := make([]*Metric, 0, len(m)) - for m := range m { + res := make([]*Metric, 0, len(peerMetricsGroups)) + populateAndPublish(peerMetricsGroups, func(m Metric) bool { + if m.VariableLabels == nil { + m.VariableLabels = make(map[string]string, 1) + } + m.VariableLabels[serverName] = globalLocalNodeName res = append(res, &m) - } + return true + }) return aoMetricsGroup.NewWith(res), nil } // GetPeerBucketMetrics gets the metrics to be federated across peers. func (s *peerRESTServer) GetPeerBucketMetrics(_ *grid.MSS) (*grid.Array[*Metric], *grid.RemoteErr) { - m := ReportMetrics(context.Background(), bucketPeerMetricsGroups) - res := make([]*Metric, 0, len(m)) - for m := range m { + res := make([]*Metric, 0, len(bucketPeerMetricsGroups)) + populateAndPublish(bucketPeerMetricsGroups, func(m Metric) bool { + if m.VariableLabels == nil { + m.VariableLabels = make(map[string]string, 1) + } + m.VariableLabels[serverName] = globalLocalNodeName res = append(res, &m) - } + return true + }) return aoMetricsGroup.NewWith(res), nil } diff --git a/internal/grid/types.go b/internal/grid/types.go index 0d579c1c2..f60f29d24 100644 --- a/internal/grid/types.go +++ b/internal/grid/types.go @@ -595,8 +595,10 @@ func (p *ArrayOf[T]) newA(sz uint32) []T { } func (p *ArrayOf[T]) putA(v []T) { - for _, t := range v { + var zero T // nil + for i, t := range v { p.ePool.Put(t) + v[i] = zero } if v != nil { v = v[:0]