Environment#batch and forcing disable through env var

This commit is contained in:
Mitchell Hashimoto 2013-03-21 19:35:40 -07:00
parent 54f7930b84
commit d6a84b5ca4
4 changed files with 80 additions and 7 deletions

View File

@ -6,23 +6,46 @@ module Vagrant
# This class executes multiple actions as a single batch, parallelizing # This class executes multiple actions as a single batch, parallelizing
# the action calls if possible. # the action calls if possible.
class BatchAction class BatchAction
def initialize def initialize(disable_parallel=false)
@actions = [] @actions = []
@disable_parallel = disable_parallel
@logger = Log4r::Logger.new("vagrant::batch_action") @logger = Log4r::Logger.new("vagrant::batch_action")
end 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) def action(machine, action, options=nil)
@actions << [machine, action, options] @actions << [machine, action, options]
end 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 def run
par = true par = true
if @disable_parallel
par = false
@logger.info("Disabled parallelization by force.")
end
if par
@actions.each do |machine, _, _| @actions.each do |machine, _, _|
if !machine.provider_options[:parallel] if !machine.provider_options[:parallel]
@logger.info("Disabling parallelization because provider doesn't support it: #{machine.provider_name}")
par = false par = false
break break
end end
end end
end
@logger.info("Batch action will parallelize: #{par.inspect}") @logger.info("Batch action will parallelize: #{par.inspect}")
@ -35,6 +58,9 @@ module Vagrant
threads << thread threads << thread
end 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) threads.map(&:join)
end end
end end

View File

@ -188,6 +188,21 @@ module Vagrant
result result
end 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 # This returns the provider name for the default provider for this
# environment. The provider returned is currently hardcoded to "virtualbox" # environment. The provider returned is currently hardcoded to "virtualbox"
# but one day should be a detected valid, best-case provider for this # but one day should be a detected valid, best-case provider for this

View File

@ -5,10 +5,12 @@ require File.expand_path("../../base", __FILE__)
describe Vagrant::BatchAction do describe Vagrant::BatchAction do
let(:called_actions) { [] } let(:called_actions) { [] }
let!(:lock) { Mutex.new } let!(:lock) { Mutex.new }
let(:provider_name) { "test" }
let(:provider_options) { {} } let(:provider_options) { {} }
def new_machine(options) def new_machine(options)
double("machine").tap do |m| double("machine").tap do |m|
m.stub(:provider_name => provider_name)
m.stub(:provider_options => options) m.stub(:provider_options => options)
m.stub(:action) do |action, opts| m.stub(:action) do |action, opts|
lock.synchronize do lock.synchronize do

View File

@ -46,6 +46,36 @@ describe Vagrant::Environment do
end end
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 describe "current working directory" do
it "is the cwd by default" do it "is the cwd by default" do
Dir.mktmpdir do |temp_dir| Dir.mktmpdir do |temp_dir|