class Bundler::ParallelInstaller

属性

size[R]

公共类方法

call(*args, **kwargs) 点击切换源码
# File bundler/installer/parallel_installer.rb, line 65
def self.call(*args, **kwargs)
  new(*args, **kwargs).call
end
new(installer, all_specs, size, standalone, force, local: false, skip: nil) 点击切换源码
# File bundler/installer/parallel_installer.rb, line 71
def initialize(installer, all_specs, size, standalone, force, local: false, skip: nil)
  @installer = installer
  @size = size
  @standalone = standalone
  @force = force
  @local = local
  @specs = all_specs.map {|s| SpecInstallation.new(s) }
  @specs.each do |spec_install|
    spec_install.state = :installed if skip.include?(spec_install.name)
  end if skip
  @spec_set = all_specs
  @rake = @specs.find {|s| s.name == "rake" unless s.installed? }
end

公共实例方法

call() 点击切换源码
# File bundler/installer/parallel_installer.rb, line 85
def call
  if @rake
    do_install(@rake, 0)
    Gem::Specification.reset
  end

  if @size > 1
    install_with_worker
  else
    install_serially
  end

  handle_error if failed_specs.any?
  @specs
ensure
  worker_pool&.stop
end

私有实例方法

do_install(spec_install, worker_num) 点击切换源码
# File bundler/installer/parallel_installer.rb, line 128
def do_install(spec_install, worker_num)
  Plugin.hook(Plugin::Events::GEM_BEFORE_INSTALL, spec_install)
  gem_installer = Bundler::GemInstaller.new(
    spec_install.spec, @installer, @standalone, worker_num, @force, @local
  )
  success, message = gem_installer.install_from_spec
  if success
    spec_install.state = :installed
    spec_install.post_install_message = message unless message.nil?
  else
    spec_install.error = "#{message}\n\n#{require_tree_for_spec(spec_install.spec)}"
    spec_install.state = :failed
  end
  Plugin.hook(Plugin::Events::GEM_AFTER_INSTALL, spec_install)
  spec_install
end
enqueue_specs() 点击切换源码

remains 哈希中的键表示未安装的 gem 规范。我们将所有没有任何依赖关系的 gem 规范入队。稍后,我们再次调用此 lambda 来安装依赖于先前安装的规范的规范。我们将继续直到所有规范都安装完毕。

# File bundler/installer/parallel_installer.rb, line 188
def enqueue_specs
  installed_specs = {}
  @specs.each do |spec|
    next unless spec.installed?
    installed_specs[spec.name] = true
  end

  @specs.each do |spec|
    if spec.ready_to_enqueue? && spec.dependencies_installed?(installed_specs)
      spec.state = :enqueued
      worker_pool.enq spec
    end
  end
end
failed_specs() 点击切换源码
# File bundler/installer/parallel_installer.rb, line 105
def failed_specs
  @specs.select(&:failed?)
end
finished_installing?() 点击切换源码
# File bundler/installer/parallel_installer.rb, line 155
def finished_installing?
  @specs.all? do |spec|
    return true if spec.failed?
    spec.installed?
  end
end
handle_error() 点击切换源码
# File bundler/installer/parallel_installer.rb, line 162
def handle_error
  errors = failed_specs.map(&:error)
  if exception = errors.find {|e| e.is_a?(Bundler::BundlerError) }
    raise exception
  end
  raise Bundler::InstallError, errors.join("\n\n")
end
install_serially() 点击切换源码
# File bundler/installer/parallel_installer.rb, line 114
def install_serially
  until finished_installing?
    raise "failed to find a spec to enqueue while installing serially" unless spec_install = @specs.find(&:ready_to_enqueue?)
    spec_install.state = :enqueued
    do_install(spec_install, 0)
  end
end
install_with_worker() 点击切换源码
# File bundler/installer/parallel_installer.rb, line 109
def install_with_worker
  enqueue_specs
  process_specs until finished_installing?
end
process_specs() 点击切换源码

将一个规范出队,并保存其安装后消息,然后将剩余的规范入队。有些规范可能必须等到此规范安装完成后才能进行处理,因此每次出队后调用“enqueue_specs”非常重要。

# File bundler/installer/parallel_installer.rb, line 150
def process_specs
  worker_pool.deq
  enqueue_specs
end
require_tree_for_spec(spec) 点击切换源码
# File bundler/installer/parallel_installer.rb, line 170
def require_tree_for_spec(spec)
  tree = @spec_set.what_required(spec)
  t = String.new("In #{File.basename(SharedHelpers.default_gemfile)}:\n")
  tree.each_with_index do |s, depth|
    t << "  " * depth.succ << s.name
    unless tree.last == s
      t << %( was resolved to #{s.version}, which depends on)
    end
    t << %(\n)
  end
  t
end
worker_pool() 点击切换源码
# File bundler/installer/parallel_installer.rb, line 122
def worker_pool
  @worker_pool ||= Bundler::Worker.new @size, "Parallel Installer", lambda {|spec_install, worker_num|
    do_install(spec_install, worker_num)
  }
end