From c8bf3341049b6b49df6af1d4324f24081e0b16d9 Mon Sep 17 00:00:00 2001 From: John Hawthorn Date: Mon, 1 Apr 2019 12:22:57 -0700 Subject: Only clear template caches in dev after changes (#35629) --- actionview/CHANGELOG.md | 8 ++++ actionview/lib/action_view.rb | 1 + actionview/lib/action_view/cache_expiry.rb | 49 +++++++++++++++++++++++++ actionview/lib/action_view/digestor.rb | 6 --- actionview/lib/action_view/railtie.rb | 2 +- actionview/lib/action_view/template/resolver.rb | 2 + 6 files changed, 61 insertions(+), 7 deletions(-) create mode 100644 actionview/lib/action_view/cache_expiry.rb diff --git a/actionview/CHANGELOG.md b/actionview/CHANGELOG.md index 17a5782f9f..0d1833d1de 100644 --- a/actionview/CHANGELOG.md +++ b/actionview/CHANGELOG.md @@ -1,3 +1,11 @@ +* Only clear ActionView cache in development on file changes + + To speed up development mode, view caches are only cleared when files in + the view paths have changed. Applications which have implemented custom + ActionView::Resolver subclasses may need to add their own cache clearing. + + *John Hawthorn* + ## Rails 6.0.0.beta3 (March 11, 2019) ## * Only accept formats from registered mime types diff --git a/actionview/lib/action_view.rb b/actionview/lib/action_view.rb index 8cb4648a67..f398ba0ff0 100644 --- a/actionview/lib/action_view.rb +++ b/actionview/lib/action_view.rb @@ -81,6 +81,7 @@ module ActionView end end + autoload :CacheExpiry autoload :TestCase def self.eager_load! diff --git a/actionview/lib/action_view/cache_expiry.rb b/actionview/lib/action_view/cache_expiry.rb new file mode 100644 index 0000000000..820afc093d --- /dev/null +++ b/actionview/lib/action_view/cache_expiry.rb @@ -0,0 +1,49 @@ +# frozen_string_literal: true + +module ActionView + class CacheExpiry + class Executor + def initialize(watcher:) + @cache_expiry = CacheExpiry.new(watcher: watcher) + end + + def before(target) + @cache_expiry.clear_cache_if_necessary + end + end + + def initialize(watcher:) + @watched_dirs = nil + @watcher_class = watcher + @watcher = nil + end + + def clear_cache_if_necessary + watched_dirs = dirs_to_watch + if watched_dirs != @watched_dirs + @watched_dirs = watched_dirs + @watcher = @watcher_class.new([], watched_dirs) do + clear_cache + end + @watcher.execute + else + @watcher.execute_if_updated + end + end + + def clear_cache + ActionView::LookupContext::DetailsKey.clear + end + + private + + def dirs_to_watch + fs_paths = all_view_paths.grep(FileSystemResolver) + fs_paths.map(&:path).sort.uniq + end + + def all_view_paths + ActionView::ViewPaths.all_view_paths.flat_map(&:paths) + end + end +end diff --git a/actionview/lib/action_view/digestor.rb b/actionview/lib/action_view/digestor.rb index 9fa8d7eab1..97a6da3634 100644 --- a/actionview/lib/action_view/digestor.rb +++ b/actionview/lib/action_view/digestor.rb @@ -6,12 +6,6 @@ module ActionView class Digestor @@digest_mutex = Mutex.new - module PerExecutionDigestCacheExpiry - def self.before(target) - ActionView::LookupContext::DetailsKey.clear - end - end - class << self # Supported options: # diff --git a/actionview/lib/action_view/railtie.rb b/actionview/lib/action_view/railtie.rb index a25e1d3d02..8bd526cdf9 100644 --- a/actionview/lib/action_view/railtie.rb +++ b/actionview/lib/action_view/railtie.rb @@ -81,7 +81,7 @@ module ActionView initializer "action_view.per_request_digest_cache" do |app| ActiveSupport.on_load(:action_view) do unless ActionView::Resolver.caching? - app.executor.to_run ActionView::Digestor::PerExecutionDigestCacheExpiry + app.executor.to_run ActionView::CacheExpiry::Executor.new(watcher: app.config.file_watcher) end end end diff --git a/actionview/lib/action_view/template/resolver.rb b/actionview/lib/action_view/template/resolver.rb index 3b4c8a94bc..095e6cc3a1 100644 --- a/actionview/lib/action_view/template/resolver.rb +++ b/actionview/lib/action_view/template/resolver.rb @@ -280,6 +280,8 @@ module ActionView # A resolver that loads files from the filesystem. class FileSystemResolver < PathResolver + attr_reader :path + def initialize(path, pattern = nil) raise ArgumentError, "path already is a Resolver class" if path.is_a?(Resolver) super(pattern) -- cgit v1.2.3