From d6a84b5ca41d6b3c517145be7694276bd68be318 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Thu, 21 Mar 2013 19:35:40 -0700 Subject: [PATCH] Environment#batch and forcing disable through env var --- lib/vagrant/batch_action.rb | 40 +++++++++++++++++++++----- lib/vagrant/environment.rb | 15 ++++++++++ test/unit/vagrant/batch_action_test.rb | 2 ++ test/unit/vagrant/environment_test.rb | 30 +++++++++++++++++++ 4 files changed, 80 insertions(+), 7 deletions(-) diff --git a/lib/vagrant/batch_action.rb b/lib/vagrant/batch_action.rb index f12dbf204..8aabc1ba4 100644 --- a/lib/vagrant/batch_action.rb +++ b/lib/vagrant/batch_action.rb @@ -6,21 +6,44 @@ module Vagrant # This class executes multiple actions as a single batch, parallelizing # the action calls if possible. class BatchAction - def initialize - @actions = [] - @logger = Log4r::Logger.new("vagrant::batch_action") + def initialize(disable_parallel=false) + @actions = [] + @disable_parallel = disable_parallel + @logger = Log4r::Logger.new("vagrant::batch_action") end + # Add an action to the batch of actions that will be run. + # + # This will **not** run the action now. The action will be run + # when {#run} is called. + # + # @param [Machine] machine The machine to run the action on + # @param [Symbol] action The action to run + # @param [Hash] options Any additional options to send in. def action(machine, action, options=nil) @actions << [machine, action, options] end + # Run all the queued up actions, parallelizing if possible. + # + # This will parallelize if and only if the provider of every machine + # supports parallelization. Parallelizing can additionally be disabled + # by passing the option into the initializer of this class. def run par = true - @actions.each do |machine, _, _| - if !machine.provider_options[:parallel] - par = false - break + + if @disable_parallel + par = false + @logger.info("Disabled parallelization by force.") + end + + if par + @actions.each do |machine, _, _| + if !machine.provider_options[:parallel] + @logger.info("Disabling parallelization because provider doesn't support it: #{machine.provider_name}") + par = false + break + end end end @@ -35,6 +58,9 @@ module Vagrant threads << thread end + # Join the threads, which will return immediately if parallelization + # if disabled, because we already joined on them. Otherwise, this + # will wait for completion of all threads. threads.map(&:join) end end diff --git a/lib/vagrant/environment.rb b/lib/vagrant/environment.rb index 7027e9754..a1d8469a4 100644 --- a/lib/vagrant/environment.rb +++ b/lib/vagrant/environment.rb @@ -188,6 +188,21 @@ module Vagrant result end + # This creates a new batch action, yielding it, and then running it + # once the block is called. + # + # This handles the case where batch actions are disabled by the + # VAGRANT_NO_PARALLEL environmental variable. + def batch + BatchAction.new(!!ENV["VAGRANT_NO_PARALLEL"]).tap do |b| + # Yield it so that the caller can setup actions + yield b + + # And run it! + b.run + end + end + # This returns the provider name for the default provider for this # environment. The provider returned is currently hardcoded to "virtualbox" # but one day should be a detected valid, best-case provider for this diff --git a/test/unit/vagrant/batch_action_test.rb b/test/unit/vagrant/batch_action_test.rb index 55bb95cfd..b43206836 100644 --- a/test/unit/vagrant/batch_action_test.rb +++ b/test/unit/vagrant/batch_action_test.rb @@ -5,10 +5,12 @@ require File.expand_path("../../base", __FILE__) describe Vagrant::BatchAction do let(:called_actions) { [] } let!(:lock) { Mutex.new } + let(:provider_name) { "test" } let(:provider_options) { {} } def new_machine(options) double("machine").tap do |m| + m.stub(:provider_name => provider_name) m.stub(:provider_options => options) m.stub(:action) do |action, opts| lock.synchronize do diff --git a/test/unit/vagrant/environment_test.rb b/test/unit/vagrant/environment_test.rb index dbca0a811..82cc3e630 100644 --- a/test/unit/vagrant/environment_test.rb +++ b/test/unit/vagrant/environment_test.rb @@ -46,6 +46,36 @@ describe Vagrant::Environment do end end + describe "batching" do + let(:batch) do + double("batch") do |b| + b.stub(:run) + end + end + + context "without the disabling env var" do + it "should run without disabling parallelization" do + with_temp_env("VAGRANT_NO_PARALLEL" => nil) do + Vagrant::BatchAction.should_receive(:new).with(false).and_return(batch) + batch.should_receive(:run) + + instance.batch {} + end + end + end + + context "with the disabling env var" do + it "should run with disabling parallelization" do + with_temp_env("VAGRANT_NO_PARALLEL" => "yes") do + Vagrant::BatchAction.should_receive(:new).with(true).and_return(batch) + batch.should_receive(:run) + + instance.batch {} + end + end + end + end + describe "current working directory" do it "is the cwd by default" do Dir.mktmpdir do |temp_dir|