diff --git a/rakelib/plugins_docs_dependencies.rake b/rakelib/plugins_docs_dependencies.rake index c01d1d27d82..b9ef6224141 100644 --- a/rakelib/plugins_docs_dependencies.rake +++ b/rakelib/plugins_docs_dependencies.rake @@ -126,6 +126,7 @@ class PluginVersionWorking end def try_plugin(plugin, successful_dependencies) + Bundler::DepProxy.__clear! builder = Bundler::Dsl.new gemfile = LogStash::Gemfile.new(File.new(LogStash::Environment::GEMFILE_PATH, "r+")).load gemfile.update(plugin) @@ -203,6 +204,29 @@ task :generate_plugins_version do end end end + DepProxy.class_eval do + # Bundler caches it's dep-proxy objects (which contain Gem::Dependency objects) from all resolutions. + # The Hash itself continues to grow between dependency resolutions and hold up a lot of memory, to avoid + # the issue we expose a way of clear-ing the cached objects before each plugin resolution. + def self.__clear! + @proxies.clear + end + end + + Fetcher::CompactIndex.class_eval do + alias_method :__bundle_worker, :bundle_worker + # The compact index is built using multiple threads and this is hard-coded atm to 25 threads: + # `Bundler::Worker.new(Bundler.current_ruby.rbx? ? 1 : 25, worker_name, func)` + # each thread might built up a Bundler::Source::Rubygems object which retains more than 100MB. + # By limiting the worker thread count we make sure not to produce too many of these objects. + def bundle_worker(func = nil) + __bundle_worker(func).tap do |worker| + size = worker.instance_variable_get(:@size) + fail("@size = #{size.inspect} is no longer an integer") unless size.is_a?(Integer) + worker.instance_variable_set(:@size, 2) + end + end + end end PluginVersionWorking.new.generate