From 30461cc2971cad20f5278fd0cb7a25aabc29a6a6 Mon Sep 17 00:00:00 2001 From: Andy Bursavich Date: Thu, 3 Dec 2020 06:42:19 -0800 Subject: [PATCH] Fix schema initialization paths The initialized channel was only closed if the schema's cacheStore did not contain the embeddedCacheKey and there were no errors parsing relations. If the key existed or an error occurred, it would not be closed. This could leave other goroutines waiting for synchronization that will never occur. Additionally, the other code paths that wait for initialization to complete did not return the possible error. --- schema/schema.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/schema/schema.go b/schema/schema.go index da4be305..ab37878d 100644 --- a/schema/schema.go +++ b/schema/schema.go @@ -92,7 +92,7 @@ func Parse(dest interface{}, cacheStore *sync.Map, namer Namer) (*Schema, error) if v, ok := cacheStore.Load(modelType); ok { s := v.(*Schema) <-s.initialized - return s, nil + return s, s.err } modelValue := reflect.New(modelType) @@ -224,6 +224,7 @@ func Parse(dest interface{}, cacheStore *sync.Map, namer Namer) (*Schema, error) } if s, loaded := cacheStore.LoadOrStore(modelType, schema); !loaded { + defer close(schema.initialized) if _, embedded := schema.cacheStore.Load(embeddedCacheKey); !embedded { for _, field := range schema.Fields { if field.DataType == "" && (field.Creatable || field.Updatable || field.Readable) { @@ -249,11 +250,10 @@ func Parse(dest interface{}, cacheStore *sync.Map, namer Namer) (*Schema, error) field.Schema.DeleteClauses = append(field.Schema.DeleteClauses, fc.DeleteClauses(field)...) } } - close(schema.initialized) } } else { - <-s.(*Schema).initialized - return s.(*Schema), nil + schema = s.(*Schema) + <-schema.initialized } return schema, schema.err