Register implements Registerer.
(c Collector)
| 268 | |
| 269 | // Register implements Registerer. |
| 270 | func (r *Registry) Register(c Collector) error { |
| 271 | var ( |
| 272 | descChan = make(chan *Desc, capDescChan) |
| 273 | newDescIDs = map[uint64]struct{}{} |
| 274 | newDimHashesByName = map[string]uint64{} |
| 275 | collectorID uint64 // All desc IDs XOR'd together. |
| 276 | duplicateDescErr error |
| 277 | ) |
| 278 | go func() { |
| 279 | c.Describe(descChan) |
| 280 | close(descChan) |
| 281 | }() |
| 282 | r.mtx.Lock() |
| 283 | defer func() { |
| 284 | // Drain channel in case of premature return to not leak a goroutine. |
| 285 | for range descChan { |
| 286 | } |
| 287 | r.mtx.Unlock() |
| 288 | }() |
| 289 | // Conduct various tests... |
| 290 | for desc := range descChan { |
| 291 | |
| 292 | // Is the descriptor valid at all? |
| 293 | if desc.err != nil { |
| 294 | return fmt.Errorf("descriptor %s is invalid: %w", desc, desc.err) |
| 295 | } |
| 296 | |
| 297 | // Is the descID unique? |
| 298 | // (In other words: Is the fqName + constLabel combination unique?) |
| 299 | if _, exists := r.descIDs[desc.id]; exists { |
| 300 | duplicateDescErr = fmt.Errorf("descriptor %s already exists with the same fully-qualified name and const label values", desc) |
| 301 | } |
| 302 | // If it is not a duplicate desc in this collector, XOR it to |
| 303 | // the collectorID. (We allow duplicate descs within the same |
| 304 | // collector, but their existence must be a no-op.) |
| 305 | if _, exists := newDescIDs[desc.id]; !exists { |
| 306 | newDescIDs[desc.id] = struct{}{} |
| 307 | collectorID ^= desc.id |
| 308 | } |
| 309 | |
| 310 | // Are all the label names and the help string consistent with |
| 311 | // previous descriptors of the same name? |
| 312 | // First check existing descriptors... |
| 313 | if dimHash, exists := r.dimHashesByName[desc.fqName]; exists { |
| 314 | if dimHash != desc.dimHash { |
| 315 | return fmt.Errorf("a previously registered descriptor with the same fully-qualified name as %s has different label names or a different help string", desc) |
| 316 | } |
| 317 | continue |
| 318 | } |
| 319 | |
| 320 | // ...then check the new descriptors already seen. |
| 321 | if dimHash, exists := newDimHashesByName[desc.fqName]; exists { |
| 322 | if dimHash != desc.dimHash { |
| 323 | return fmt.Errorf("descriptors reported by collector have inconsistent label names or help strings for the same fully-qualified name, offender is %s", desc) |
| 324 | } |
| 325 | continue |
| 326 | } |
| 327 | newDimHashesByName[desc.fqName] = desc.dimHash |