Merge pull request #513 from prometheus/beorn7/registry

Fix the race in the registry
This commit is contained in:
Björn Rabenstein 2018-12-06 18:41:01 +01:00 committed by GitHub
commit 3c1fbfb44a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 22 additions and 10 deletions

View File

@ -872,7 +872,13 @@ func checkMetricConsistency(
h = hashAddByte(h, separatorByte) h = hashAddByte(h, separatorByte)
// Make sure label pairs are sorted. We depend on it for the consistency // Make sure label pairs are sorted. We depend on it for the consistency
// check. // check.
sort.Sort(labelPairSorter(dtoMetric.Label)) if !sort.IsSorted(labelPairSorter(dtoMetric.Label)) {
// We cannot sort dtoMetric.Label in place as it is immutable by contract.
copiedLabels := make([]*dto.LabelPair, len(dtoMetric.Label))
copy(copiedLabels, dtoMetric.Label)
sort.Sort(labelPairSorter(copiedLabels))
dtoMetric.Label = copiedLabels
}
for _, lp := range dtoMetric.Label { for _, lp := range dtoMetric.Label {
h = hashAdd(h, lp.GetName()) h = hashAdd(h, lp.GetName())
h = hashAddByte(h, separatorByte) h = hashAddByte(h, separatorByte)
@ -903,8 +909,8 @@ func checkDescConsistency(
} }
// Is the desc consistent with the content of the metric? // Is the desc consistent with the content of the metric?
lpsFromDesc := make([]*dto.LabelPair, 0, len(dtoMetric.Label)) lpsFromDesc := make([]*dto.LabelPair, len(desc.constLabelPairs), len(dtoMetric.Label))
lpsFromDesc = append(lpsFromDesc, desc.constLabelPairs...) copy(lpsFromDesc, desc.constLabelPairs)
for _, l := range desc.variableLabels { for _, l := range desc.variableLabels {
lpsFromDesc = append(lpsFromDesc, &dto.LabelPair{ lpsFromDesc = append(lpsFromDesc, &dto.LabelPair{
Name: proto.String(l), Name: proto.String(l),

View File

@ -21,6 +21,7 @@ package prometheus_test
import ( import (
"bytes" "bytes"
"fmt"
"io/ioutil" "io/ioutil"
"math/rand" "math/rand"
"net/http" "net/http"
@ -783,6 +784,11 @@ func TestAlreadyRegistered(t *testing.T) {
// same HistogramVec is registered concurrently and the Gather method of the // same HistogramVec is registered concurrently and the Gather method of the
// registry is called concurrently. // registry is called concurrently.
func TestHistogramVecRegisterGatherConcurrency(t *testing.T) { func TestHistogramVecRegisterGatherConcurrency(t *testing.T) {
labelNames := make([]string, 16) // Need at least 13 to expose #512.
for i := range labelNames {
labelNames[i] = fmt.Sprint("label_", i)
}
var ( var (
reg = prometheus.NewPedanticRegistry() reg = prometheus.NewPedanticRegistry()
hv = prometheus.NewHistogramVec( hv = prometheus.NewHistogramVec(
@ -791,7 +797,7 @@ func TestHistogramVecRegisterGatherConcurrency(t *testing.T) {
Help: "This helps testing.", Help: "This helps testing.",
ConstLabels: prometheus.Labels{"foo": "bar"}, ConstLabels: prometheus.Labels{"foo": "bar"},
}, },
[]string{"one", "two", "three"}, labelNames,
) )
labelValues = []string{"a", "b", "c", "alpha", "beta", "gamma", "aleph", "beth", "gimel"} labelValues = []string{"a", "b", "c", "alpha", "beta", "gamma", "aleph", "beth", "gimel"}
quit = make(chan struct{}) quit = make(chan struct{})
@ -806,11 +812,11 @@ func TestHistogramVecRegisterGatherConcurrency(t *testing.T) {
return return
default: default:
obs := rand.NormFloat64()*.1 + .2 obs := rand.NormFloat64()*.1 + .2
hv.WithLabelValues( values := make([]string, 0, len(labelNames))
labelValues[rand.Intn(len(labelValues))], for range labelNames {
labelValues[rand.Intn(len(labelValues))], values = append(values, labelValues[rand.Intn(len(labelValues))])
labelValues[rand.Intn(len(labelValues))], }
).Observe(obs) hv.WithLabelValues(values...).Observe(obs)
} }
} }
} }
@ -848,7 +854,7 @@ func TestHistogramVecRegisterGatherConcurrency(t *testing.T) {
if len(g) != 1 { if len(g) != 1 {
t.Error("Gathered unexpected number of metric families:", len(g)) t.Error("Gathered unexpected number of metric families:", len(g))
} }
if len(g[0].Metric[0].Label) != 4 { if len(g[0].Metric[0].Label) != len(labelNames)+1 {
t.Error("Gathered unexpected number of label pairs:", len(g[0].Metric[0].Label)) t.Error("Gathered unexpected number of label pairs:", len(g[0].Metric[0].Label))
} }
} }