From 32b504ab0c51a90e472fb8e1c45a889f84e52293 Mon Sep 17 00:00:00 2001 From: Roy Hadad <39004075+royhadad@users.noreply.github.com> Date: Wed, 7 Jun 2023 14:55:29 +0300 Subject: [PATCH] perf: cache compiled rules to improve performance by 30% (#944) * perf: cache rules compiled schemas * cleanup logs * add log * cleanup * cleanuo * docs * fix lint * load schema once * add error catchere --- pkg/jsonSchemaValidator/validator.go | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/pkg/jsonSchemaValidator/validator.go b/pkg/jsonSchemaValidator/validator.go index 85efcc31e6..ac5f65462d 100644 --- a/pkg/jsonSchemaValidator/validator.go +++ b/pkg/jsonSchemaValidator/validator.go @@ -6,6 +6,7 @@ import ( "os" "strconv" "strings" + "sync" extensions "github.com/datreeio/datree/pkg/jsonSchemaValidator/extensions" "github.com/ghodss/yaml" @@ -14,10 +15,13 @@ import ( ) type JSONSchemaValidator struct { + rulesSchemasCache sync.Map } func New() *JSONSchemaValidator { - return &JSONSchemaValidator{} + return &JSONSchemaValidator{ + rulesSchemasCache: sync.Map{}, + } } type resourceMinimumCompiler struct{} @@ -70,12 +74,22 @@ func (jsv *JSONSchemaValidator) Validate(schemaContent string, yamlContent []byt compiler.RegisterExtension("customKeyRule101", extensions.CustomKeyRule101, extensions.CustomKeyRule101Compiler{}) compiler.RegisterExtension("customKeyRegoRule", extensions.CustomKeyRegoRule, extensions.CustomKeyRegoDefinitionCompiler{}) - schema, err := compiler.Compile("schema.json") - if err != nil { - return nil, err + // compiler.Compile() is an expensive operation. We cache the compiled schema in rulesSchemasCache to avoid re-compiling the same schema. + schemaAny, ok := jsv.rulesSchemasCache.Load(schemaContent) + if !ok { + compiledSchema, err := compiler.Compile("schema.json") + if err != nil { + return nil, err + } + jsv.rulesSchemasCache.Store(schemaContent, compiledSchema) + schemaAny = compiledSchema + } + schema, ok := schemaAny.(*jsonschema.Schema) + if !ok { + return nil, fmt.Errorf("failed to convert schema to *jsonschema.Schema") } - err = schema.Validate(jsonYamlContent) + err := schema.Validate(jsonYamlContent) if err != nil { if validationError, ok := err.(*jsonschema.ValidationError); ok {