Skip to content

Conversation

ySnoopyDogy
Copy link

Breaking change

Updated the signature of paths.FindPath function, to receive a RegexCache interface as a parameter.

The problem

Every time a path search is performed, each path and its fragments get a new regex compilation. For general validation purpose, this is not a big deal. The problem is, when validating the same document for different requests, hundreds of times per minute. The CPU pressure and memory usage can grow significantly for allocating every regex compilation.

The solution

To avoid all the regex recompilation, a new ValidationOption has been added to allow users to attach a Regex Cache interface, which has a Load and a Store method. The function config.WithRegexCache set the ValidationOptions. The cache is optional, so the end user that simply calls the NewValidator* function, nothing's changed.

Test and benchmarking

Every test is passing. Tests that call the FindPath function have been updated to include a per-validator cache, and some of them are cache-free. Added tests that check how many times the cache was accessed.

A benchmark was added to the validate_parameter_test.go file, that makes a sync validation through every 5 parameter validator. The results show a 50% decrease in execution time, and a 3.8x improvement in memory allocations:

go test -benchmem -run=^$ -bench ^Benchmark github.com/pb33f/libopenapi-validator/parameters 

BenchmarkValidationWithoutCache-8           4364            303001 ns/op          168440 B/op       2552 allocs/op
BenchmarkValidationWithRegexCache-8         9217            133931 ns/op           44117 B/op        676 allocs/op

Adding a cache

To add a RegexCache, just call the WithRegexCache:

myGlobalCache := &sync.Map{}

validator, errs := NewValidator(document, config.WithRegexCache(myGlobalCache))
otherValidator, errs := NewValidator(otherDocument, config.WithRegexCache(myGlobalCache))

A sync.Map is full compatible with the cache, as it is a interface with Load and Store functions. Cleaning and managing the cache staleness must be done by the end user.

Copy link

codecov bot commented Oct 14, 2025

Codecov Report

❌ Patch coverage is 98.38710% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 97.11%. Comparing base (69c8af1) to head (8ad97ff).

Files with missing lines Patch % Lines
parameters/path_parameters.go 94.44% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #190      +/-   ##
==========================================
+ Coverage   97.09%   97.11%   +0.01%     
==========================================
  Files          41       41              
  Lines        4403     4433      +30     
==========================================
+ Hits         4275     4305      +30     
  Misses        128      128              
Flag Coverage Δ
unittests 97.11% <98.38%> (+0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@daveshanley
Copy link
Member

this is clean! did you use AI for this or is it homegrown?

@ySnoopyDogy
Copy link
Author

this is clean! did you use AI for this or is it homegrown?

I only used AI for helping to develop the tests to ensure the coverage at path_parameters.go. The rest of the code was made by me. A profiler revealed the regex issue:

image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants