registry.go
func (r *Registry) Fetch(name string, tags []string, factory func() interface{}) interface{} {
	key := MetricID(name, tags)

	r.mutex.RLock()
	v, ok := r.instruments[key]
	r.mutex.RUnlock()
	if ok {
		return v
	}

	r.mutex.Lock()
	defer r.mutex.Unlock()

	if v, ok = r.instruments[key]; !ok {
		switch v = factory(); v.(type) {
		case Discrete, Sample:
			r.instruments[key] = v
		}
	}
	return v
}
func (r *Registry) Fetch(name string, tags []string, factory func() interface{}) interface{} {
	key := MetricID(name, tags)

	r.mutex.RLock()
	v, ok := r.instruments[key]
	r.mutex.RUnlock()
	if ok {
		return v
	}

	r.mutex.Lock()
	defer r.mutex.Unlock()

	if v, ok = r.instruments[key]; !ok {
		switch v = factory(); v.(type) {
		case Discrete, Sample:
			r.instruments[key] = v
		}
	}
	return v
}
// Fetch returns an instrument from the Registry or creates a new one
// using the provided factory.