From 02b2291375909aaff4df5792f7e87427d56c7a2a Mon Sep 17 00:00:00 2001 From: Timothy Messier Date: Thu, 7 Oct 2021 09:25:17 -0400 Subject: [PATCH] feat(subtypes): Make Registry thread-safe --- internal/types/subtypes/registry.go | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/internal/types/subtypes/registry.go b/internal/types/subtypes/registry.go index 27423ad7a..10462cbd5 100644 --- a/internal/types/subtypes/registry.go +++ b/internal/types/subtypes/registry.go @@ -4,6 +4,7 @@ package subtypes import ( "fmt" "strings" + "sync" "github.com/hashicorp/boundary/internal/errors" ) @@ -22,13 +23,14 @@ func (t Subtype) String() string { // Registry stores a collection of boundary resource subtypes along with their // prefixes and allows for translating prefixes back to registered subtypes. -// Registry is not thread safe. type Registry struct { subtypesPrefixes map[string]Subtype knownSubtypes map[Subtype]interface{} + + sync.RWMutex } -// New Registry creates a new boundary resource subtype registry. +// NewRegistry creates a new boundary resource subtype registry. func NewRegistry() *Registry { return &Registry{ subtypesPrefixes: make(map[string]Subtype), @@ -39,6 +41,9 @@ func NewRegistry() *Registry { // SubtypeFromType returns the Subtype from the provided string or if // no Subtype was registered with that string Unknown is returned. func (r *Registry) SubtypeFromType(t string) Subtype { + r.RLock() + defer r.RUnlock() + st := Subtype(t) if _, ok := r.knownSubtypes[st]; !ok { return UnknownSubtype @@ -49,6 +54,9 @@ func (r *Registry) SubtypeFromType(t string) Subtype { // SubtypeFromId returns the Subtype from the provided id if the id's prefix // was registered with a Subtype. Otherwise Unknown is returned. func (r *Registry) SubtypeFromId(id string) Subtype { + r.RLock() + defer r.RUnlock() + i := strings.Index(id, "_") if i == -1 { return UnknownSubtype @@ -66,6 +74,9 @@ func (r *Registry) SubtypeFromId(id string) Subtype { // an error if the subtype has already been registered or if any of the // prefixes are associated with another subtype. func (r *Registry) Register(subtype Subtype, prefixes ...string) error { + r.Lock() + defer r.Unlock() + const op = "subtypes.(Registry).Register" if _, present := r.knownSubtypes[subtype]; present { return errors.NewDeprecated(errors.SubtypeAlreadyRegistered, op, fmt.Sprintf("subtype %q already registered", subtype))