diff --git a/CHANGELOG.md b/CHANGELOG.md index 7eb17cd1..1f9539c5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +- `OpenapiFirst::FileLoader` will now cache the contents of files that have been loaded. This cache + is keyed on the file's path. If you need to reload your OpenAPI definition for tests or server hot + reloading, you can run `OpenapiFirst::FileLoader.clear_cache!`. + ## 3.2.1 - Don't raise `UnknownQueryParameterError` if request is ignored in tests. Fixes [#441](https://github.com/ahx/openapi_first/issues/441). diff --git a/lib/openapi_first/file_loader.rb b/lib/openapi_first/file_loader.rb index 45082412..8dc4dcd1 100644 --- a/lib/openapi_first/file_loader.rb +++ b/lib/openapi_first/file_loader.rb @@ -6,17 +6,32 @@ module OpenapiFirst # @!visibility private module FileLoader + @cache = {} + @mutex = Mutex.new + module_function def load(file_path) - raise FileNotFoundError, "File not found #{file_path.inspect}" unless File.exist?(file_path) + @cache[file_path] || @mutex.synchronize do + @cache[file_path] ||= begin + raise FileNotFoundError, "File not found #{file_path.inspect}" unless File.exist?(file_path) + + body = File.read(file_path) + extname = File.extname(file_path) - body = File.read(file_path) - extname = File.extname(file_path) - return ::JSON.parse(body) if extname == '.json' - return YAML.unsafe_load(body) if ['.yaml', '.yml'].include?(extname) + if extname == '.json' + ::JSON.parse(body) + elsif ['.yaml', '.yml'].include?(extname) + YAML.unsafe_load(body) + else + body + end + end + end + end - body + def clear_cache! + @mutex.synchronize { @cache.clear } end end end