aboutsummaryrefslogtreecommitdiffstats
path: root/activesupport
diff options
context:
space:
mode:
Diffstat (limited to 'activesupport')
-rw-r--r--activesupport/CHANGELOG.md14
-rw-r--r--activesupport/activesupport.gemspec2
-rw-r--r--activesupport/lib/active_support/dependencies/zeitwerk_integration.rb26
-rw-r--r--activesupport/lib/active_support/descendants_tracker.rb11
4 files changed, 35 insertions, 18 deletions
diff --git a/activesupport/CHANGELOG.md b/activesupport/CHANGELOG.md
index db9c7e96f3..57e03b5e12 100644
--- a/activesupport/CHANGELOG.md
+++ b/activesupport/CHANGELOG.md
@@ -1,3 +1,17 @@
+* The Zeitwerk compatibility interface for `ActiveSupport::Dependencies` no
+ longer implements `autoloaded_constants` or `autoloaded?` (undocumented,
+ anyway). Experience shows introspection does not have many use cases, and
+ troubleshooting is done by logging. With this design trade-off we are able
+ to use even less memory in all environments.
+
+ *Xavier Noria*
+
+* Depends on Zeitwerk 2, which stores less metadata if reloading is disabled
+ and hence uses less memory when `config.cache_classes` is `true`, a standard
+ setup in production.
+
+ *Xavier Noria*
+
* In `:zeitwerk` mode, eager load directories in engines and applications only
if present in their respective `config.eager_load_paths`.
diff --git a/activesupport/activesupport.gemspec b/activesupport/activesupport.gemspec
index bf0fe0f76d..dd2340cdd3 100644
--- a/activesupport/activesupport.gemspec
+++ b/activesupport/activesupport.gemspec
@@ -34,5 +34,5 @@ Gem::Specification.new do |s|
s.add_dependency "tzinfo", "~> 1.1"
s.add_dependency "minitest", "~> 5.1"
s.add_dependency "concurrent-ruby", "~> 1.0", ">= 1.0.2"
- s.add_dependency "zeitwerk", "~> 1.4", ">= 1.4.3"
+ s.add_dependency "zeitwerk", "~> 2.1", ">= 2.1.2"
end
diff --git a/activesupport/lib/active_support/dependencies/zeitwerk_integration.rb b/activesupport/lib/active_support/dependencies/zeitwerk_integration.rb
index a43d03cf09..f16a9f7e57 100644
--- a/activesupport/lib/active_support/dependencies/zeitwerk_integration.rb
+++ b/activesupport/lib/active_support/dependencies/zeitwerk_integration.rb
@@ -9,7 +9,11 @@ module ActiveSupport
module Decorations
def clear
Dependencies.unload_interlock do
- Rails.autoloaders.main.reload
+ begin
+ Rails.autoloaders.main.reload
+ rescue Zeitwerk::ReloadingDisabledError
+ raise "reloading is disabled because config.cache_classes is true"
+ end
end
end
@@ -21,17 +25,8 @@ module ActiveSupport
ActiveSupport::Inflector.safe_constantize(cpath)
end
- def autoloaded_constants
- cpaths = []
- Rails.autoloaders.each do |autoloader|
- cpaths.concat(autoloader.loaded_cpaths.to_a)
- end
- cpaths
- end
-
- def autoloaded?(object)
- cpath = object.is_a?(Module) ? object.name : object.to_s
- Rails.autoloaders.any? { |autoloader| autoloader.loaded?(cpath) }
+ def to_unload?(cpath)
+ Rails.autoloaders.main.to_unload?(cpath)
end
def verbose=(verbose)
@@ -51,15 +46,15 @@ module ActiveSupport
end
class << self
- def take_over
- setup_autoloaders
+ def take_over(enable_reloading:)
+ setup_autoloaders(enable_reloading)
freeze_paths
decorate_dependencies
end
private
- def setup_autoloaders
+ def setup_autoloaders(enable_reloading)
Dependencies.autoload_paths.each do |autoload_path|
# Zeitwerk only accepts existing directories in `push_dir` to
# prevent misconfigurations.
@@ -72,6 +67,7 @@ module ActiveSupport
autoloader.do_not_eager_load(autoload_path) unless eager_load?(autoload_path)
end
+ Rails.autoloaders.main.enable_reloading if enable_reloading
Rails.autoloaders.each(&:setup)
end
diff --git a/activesupport/lib/active_support/descendants_tracker.rb b/activesupport/lib/active_support/descendants_tracker.rb
index 2dca990712..fe0c6991aa 100644
--- a/activesupport/lib/active_support/descendants_tracker.rb
+++ b/activesupport/lib/active_support/descendants_tracker.rb
@@ -22,11 +22,18 @@ module ActiveSupport
def clear
if defined? ActiveSupport::Dependencies
+ # to_unload? is only defined in Zeitwerk mode.
+ to_unload = if Dependencies.respond_to?(:to_unload?)
+ ->(klass) { Dependencies.to_unload?(klass.name) }
+ else
+ ->(klass) { Dependencies.autoloaded?(klass) }
+ end
+
@@direct_descendants.each do |klass, descendants|
- if ActiveSupport::Dependencies.autoloaded?(klass)
+ if to_unload[klass]
@@direct_descendants.delete(klass)
else
- descendants.reject! { |v| ActiveSupport::Dependencies.autoloaded?(v) }
+ descendants.reject! { |v| to_unload[v] }
end
end
else