PERF: Actually cache plugin manifests and asset lookups (#43178)

`Plugin::JsManager.maybe_cache` used `@cache.fetch(key, &blk)`, which
returns the block's value on a miss but never stores it, so the cache
never worked, which led to a large number of filesystem reads.

This commit fixes the cache, and also introduces
`CurrentAttributes`-based caching in development (to match what we do in
`lib/ember_assets.rb`)

`maybe_cache` is now `get_set_cache`, because it always reads through
and writes back.
This commit is contained in:
David Taylor
2026-09-03 17:03:51 +01:00
committed by GitHub
parent 4610db1056
commit 17780093e3
+19 -9
View File
@@ -2,7 +2,10 @@
module Plugin
class JsManager
@cache = {}
class Cache < ActiveSupport::CurrentAttributes
# Cache which persists for the duration of a request
attribute :request_cache
end
def self.optional_plugin_stub
"data:text/javascript,/* autogenerated missing optional plugin stub */const m=new Proxy({},{get:()=>null});export default new Proxy({},{get:()=>m});"
@@ -17,25 +20,25 @@ module Plugin
end
def self.js_asset_exists?(plugin_directory_name)
maybe_cache("js_asset_exists_#{plugin_directory_name}") do
get_set_cache("js_asset_exists_#{plugin_directory_name}") do
has_source_files_in_dir(plugin_directory_name, "assets/javascripts")
end
end
def self.admin_js_asset_exists?(plugin_directory_name)
maybe_cache("admin_js_asset_exists_#{plugin_directory_name}") do
get_set_cache("admin_js_asset_exists_#{plugin_directory_name}") do
has_source_files_in_dir(plugin_directory_name, "admin/assets/javascripts")
end
end
def self.test_js_asset_exists?(plugin_directory_name)
maybe_cache("test_js_asset_exists_#{plugin_directory_name}") do
get_set_cache("test_js_asset_exists_#{plugin_directory_name}") do
has_source_files_in_dir(plugin_directory_name, "test/javascripts")
end
end
def self.read_manifest(plugin_directory_name)
maybe_cache("manifest_#{plugin_directory_name}") do
get_set_cache("manifest_#{plugin_directory_name}") do
manifest_path =
"#{Rails.root.join("app/assets/generated/#{plugin_directory_name}/manifest.json")}"
JSON.parse(File.read(manifest_path))
@@ -236,11 +239,18 @@ module Plugin
STDERR.puts message
end
private_class_method def self.maybe_cache(key, &blk)
if Rails.env.production?
@cache.fetch(key, &blk)
private_class_method def self.get_set_cache(key, &blk)
store =
if Rails.env.development?
Cache.request_cache ||= {}
else
@production_cache ||= {}
end
if store.key?(key)
store[key]
else
blk.call
store[key] = blk.call
end
end