github.com/grafana/synthetic-monitoring-agent@v0.64.2/internal/pusher/registry.go (about)

     1  package pusher
     2  
     3  import (
     4  	"fmt"
     5  	"sort"
     6  	"sync"
     7  )
     8  
     9  // registry to register and obtain instances of the named type.
    10  //
    11  // This type is not exported to prevent creating instances without calling NewRegistry.
    12  type registry[T any] struct {
    13  	mu      sync.Mutex
    14  	entries map[string]T
    15  }
    16  
    17  func NewRegistry[T any]() *registry[T] {
    18  	var r registry[T]
    19  
    20  	r.entries = make(map[string]T)
    21  
    22  	return &r
    23  }
    24  
    25  func (r *registry[T]) Register(name string, handler T) error {
    26  	r.mu.Lock()
    27  	defer r.mu.Unlock()
    28  
    29  	if _, found := r.entries[name]; found {
    30  		return AlreadyRegisteredError(name)
    31  	}
    32  
    33  	r.entries[name] = handler
    34  
    35  	return nil
    36  }
    37  
    38  func (r *registry[T]) MustRegister(name string, handler T) {
    39  	if err := r.Register(name, handler); err != nil {
    40  		panic(err)
    41  	}
    42  }
    43  
    44  func (r *registry[T]) Lookup(name string) (T, error) {
    45  	r.mu.Lock()
    46  	defer r.mu.Unlock()
    47  
    48  	entry, found := r.entries[name]
    49  	if !found {
    50  		var (
    51  			zero T
    52  			keys []string
    53  		)
    54  		for key := range r.entries {
    55  			keys = append(keys, key)
    56  		}
    57  
    58  		sort.Strings(keys)
    59  
    60  		return zero, NotFoundError{
    61  			Requested: name,
    62  			Accepted:  keys,
    63  		}
    64  	}
    65  
    66  	return entry, nil
    67  }
    68  
    69  type NotFoundError struct {
    70  	Requested string
    71  	Accepted  []string
    72  }
    73  
    74  func (e NotFoundError) Error() string {
    75  	return fmt.Sprintf("`%s` not found. Must be one of %v", e.Requested, e.Accepted)
    76  }
    77  
    78  type AlreadyRegisteredError string
    79  
    80  func (e AlreadyRegisteredError) Error() string {
    81  	return fmt.Sprintf("entry `%s` already registered", string(e))
    82  }