From 8c96b12588cb6f8cca320ee2f7785293e8906095 Mon Sep 17 00:00:00 2001 From: Robert Vollmert Date: Mon, 9 Nov 2015 15:00:46 +0100 Subject: [PATCH] try getting metrics with a read lock, first --- prometheus/vec.go | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/prometheus/vec.go b/prometheus/vec.go index ed40f40..68f9461 100644 --- a/prometheus/vec.go +++ b/prometheus/vec.go @@ -72,13 +72,20 @@ func (m *MetricVec) Collect(ch chan<- Metric) { // with a performance overhead (for creating and processing the Labels map). // See also the GaugeVec example. func (m *MetricVec) GetMetricWithLabelValues(lvs ...string) (Metric, error) { - m.mtx.Lock() - defer m.mtx.Unlock() - h, err := m.hashLabelValues(lvs) if err != nil { return nil, err } + + m.mtx.RLock() + metric, ok := m.children[h] + m.mtx.RUnlock() + if ok { + return metric, nil + } + + m.mtx.Lock() + defer m.mtx.Unlock() return m.getOrCreateMetric(h, lvs...), nil } @@ -95,17 +102,24 @@ func (m *MetricVec) GetMetricWithLabelValues(lvs ...string) (Metric, error) { // GetMetricWithLabelValues(...string). See there for pros and cons of the two // methods. func (m *MetricVec) GetMetricWith(labels Labels) (Metric, error) { - m.mtx.Lock() - defer m.mtx.Unlock() - h, err := m.hashLabels(labels) if err != nil { return nil, err } + + m.mtx.RLock() + metric, ok := m.children[h] + m.mtx.RUnlock() + if ok { + return metric, nil + } + lvs := make([]string, len(labels)) for i, label := range m.desc.variableLabels { lvs[i] = labels[label] } + m.mtx.Lock() + defer m.mtx.Unlock() return m.getOrCreateMetric(h, lvs...), nil }