From 75f5a10b5e7a2fe9428faacf981ba97bf3bb0743 Mon Sep 17 00:00:00 2001 From: Dave Shanley Date: Mon, 18 Sep 2023 17:43:03 -0400 Subject: [PATCH] Added a render lock to stop concurrency from mashing up state in a shared model. When using a shared model for validation, concurrency can cause state read and write to crash, this is because rendering sets flags on the structs to mark them as pre-rendered and this causes all kinds of problems. This lock now keeps things orderly when running concurrent requests for validation that require schema rendering. Signed-off-by: Dave Shanley --- schema_validation/validate_schema.go | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/schema_validation/validate_schema.go b/schema_validation/validate_schema.go index 03a2b6d..d015f91 100644 --- a/schema_validation/validate_schema.go +++ b/schema_validation/validate_schema.go @@ -18,6 +18,7 @@ import ( "regexp" "strconv" "strings" + "sync" ) // SchemaValidator is an interface that defines the methods for validating a *base.Schema (V3+ Only) object. @@ -64,6 +65,8 @@ func (s *schemaValidator) ValidateSchemaBytes(schema *base.Schema, payload []byt return validateSchema(schema, payload, nil, s.logger) } +var renderLock = &sync.Mutex{} + func validateSchema(schema *base.Schema, payload []byte, decodedObject interface{}, log *zap.SugaredLogger) (bool, []*errors.ValidationError) { var validationErrors []*errors.ValidationError @@ -73,8 +76,12 @@ func validateSchema(schema *base.Schema, payload []byte, decodedObject interface return false, validationErrors } - // render the schema, to be used for validation + // render the schema, to be used for validation, stop this from running concurrently, mutations are made to state + // and, it will cause async issues. + renderLock.Lock() renderedSchema, _ := schema.RenderInline() + renderLock.Unlock() + jsonSchema, _ := utils.ConvertYAMLtoJSON(renderedSchema) if decodedObject == nil && len(payload) > 0 {