# File lib/bundler/installer/parallel_installer.rb, line 73 def self.call(*args) new(*args).call end
Returns max number of threads machine can handle with a min of 1
# File lib/bundler/installer/parallel_installer.rb, line 78 def self.max_threads [Bundler.settings[:jobs].to_i - 1, 1].max end
# File lib/bundler/installer/parallel_installer.rb, line 82 def initialize(installer, all_specs, size, standalone, force) @installer = installer @size = size @standalone = standalone @force = force @specs = all_specs.map {|s| SpecInstallation.new(s) } end
# File lib/bundler/installer/parallel_installer.rb, line 90 def call enqueue_specs process_specs until @specs.all?(&:installed?) || @specs.any?(&:failed?) handle_error if @specs.any?(&:failed?) @specs ensure worker_pool && worker_pool.stop end
Keys in the remains hash represent uninstalled gems specs. We enqueue all gem specs that do not have any dependencies. Later we call this lambda again to install specs that depended on previously installed specifications. We continue until all specs are installed.
# File lib/bundler/installer/parallel_installer.rb, line 139 def enqueue_specs @specs.select(&:ready_to_enqueue?).each do |spec| if spec.dependencies_installed? @specs spec.state = :enqueued worker_pool.enq spec end end end
# File lib/bundler/installer/parallel_installer.rb, line 126 def handle_error errors = @specs.select(&:failed?).map(&:error) if exception = errors.find {|e| e.is_a?(Bundler::BundlerError) } raise exception end raise Bundler::InstallError, errors.map(&:to_s).join("\n\n") end
Dequeue a spec and save its post-install message and then enqueue the remaining specs. Some specs might've had to wait til this spec was installed to be processed so the call to `enqueue_specs` is important after every dequeue.
# File lib/bundler/installer/parallel_installer.rb, line 120 def process_specs spec = worker_pool.deq spec.state = :installed unless spec.failed? enqueue_specs end
# File lib/bundler/installer/parallel_installer.rb, line 99 def worker_pool @worker_pool ||= Bundler::Worker.new @size, "Parallel Installer", lambda { |spec_install, worker_num| gem_installer = Bundler::GemInstaller.new( spec_install.spec, @installer, @standalone, worker_num, @force ) success, message = gem_installer.install_from_spec if success && !message.nil? spec_install.post_install_message = message elsif !success spec_install.state = :failed spec_install.error = message end spec_install } end