Merge pull request #10891 from chrisroberts/f-trigger-multithread
Update trigger abort behavior when running parallel actions
This commit is contained in:
commit
2507b68045
|
@ -71,6 +71,10 @@ module Vagrant
|
|||
thread = Thread.new do
|
||||
Thread.current[:error] = nil
|
||||
|
||||
# Note that this thread is being used for running
|
||||
# a batch action
|
||||
Thread.current[:batch_parallel_action] = par
|
||||
|
||||
# Record our pid when we started in order to figure out if
|
||||
# we've forked...
|
||||
start_pid = Process.pid
|
||||
|
@ -160,6 +164,16 @@ module Vagrant
|
|||
if !errors.empty?
|
||||
raise Errors::BatchMultiError, message: errors.join("\n\n")
|
||||
end
|
||||
|
||||
# Check if any threads set an exit code and exit if found. If
|
||||
# multiple threads have exit code values set, the first encountered
|
||||
# will be the value used.
|
||||
threads.each do |thread|
|
||||
if thread[:exit_code]
|
||||
@logger.debug("Found exit code set within batch action thread. Exiting")
|
||||
Process.exit!(thread[:exit_code])
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -300,8 +300,17 @@ module Vagrant
|
|||
#
|
||||
# @param [Integer] code Code to exit Vagrant on
|
||||
def trigger_abort(exit_code)
|
||||
@ui.warn(I18n.t("vagrant.trigger.abort"))
|
||||
Process.exit!(exit_code)
|
||||
if Thread.current[:batch_parallel_action]
|
||||
@ui.warn(I18n.t("vagrant.trigger.abort_threaded"))
|
||||
@logger.debug("Trigger abort within parallel batch action. " \
|
||||
"Setting exit code and terminating.")
|
||||
Thread.current[:exit_code] = exit_code
|
||||
Thread.current.terminate
|
||||
else
|
||||
@ui.warn(I18n.t("vagrant.trigger.abort"))
|
||||
@logger.debug("Trigger abort within non-parallel action, exiting directly")
|
||||
Process.exit!(exit_code)
|
||||
end
|
||||
end
|
||||
|
||||
# Calls the given ruby block for execution
|
||||
|
|
|
@ -297,6 +297,9 @@ en:
|
|||
Trigger configured to continue on error...
|
||||
abort: |-
|
||||
Vagrant has been configured to abort. Terminating now...
|
||||
abort_threaded: |-
|
||||
Vagrant has been configured to abort. Vagrant will terminate
|
||||
after remaining running actions have completed...
|
||||
start: |-
|
||||
Running %{type} triggers %{stage} %{action} ...
|
||||
fire_with_name: |-
|
||||
|
|
|
@ -63,5 +63,24 @@ describe Vagrant::BatchAction do
|
|||
subject.action(machine, "up")
|
||||
subject.run
|
||||
end
|
||||
|
||||
context "with provider supporting parallel actions" do
|
||||
let(:provider_options) { {parallel: true} }
|
||||
|
||||
it "should flag threads as being parallel actions" do
|
||||
parallel = nil
|
||||
subject.custom(machine) { |m| parallel = Thread.current[:batch_parallel_action] }
|
||||
subject.custom(machine) { |*_| }
|
||||
subject.run
|
||||
expect(parallel).to eq(true)
|
||||
end
|
||||
|
||||
it "should exit the process if exit_code has been set" do
|
||||
subject.custom(machine) { |m| Thread.current[:exit_code] = 1}
|
||||
subject.custom(machine) { |*_| }
|
||||
expect(Process).to receive(:exit!).with(1)
|
||||
subject.run
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -423,6 +423,37 @@ describe Vagrant::Plugin::V2::Trigger do
|
|||
expect(Process).to receive(:exit!).with(3)
|
||||
subject.send(:trigger_abort, 3)
|
||||
end
|
||||
|
||||
context "when running in parallel" do
|
||||
let(:thread) {
|
||||
@t ||= Thread.new do
|
||||
Thread.current[:batch_parallel_action] = true
|
||||
Thread.stop
|
||||
subject.send(:trigger_abort, exit_code)
|
||||
end
|
||||
}
|
||||
let(:exit_code) { 22 }
|
||||
|
||||
before do
|
||||
expect(Process).not_to receive(:exit!)
|
||||
sleep(0.1) until thread.stop?
|
||||
end
|
||||
|
||||
after { @t = nil }
|
||||
|
||||
it "should terminate the thread" do
|
||||
expect(thread).to receive(:terminate).and_call_original
|
||||
thread.wakeup
|
||||
thread.join(1) while thread.alive?
|
||||
end
|
||||
|
||||
it "should set the exit code into the thread data" do
|
||||
expect(thread).to receive(:terminate).and_call_original
|
||||
thread.wakeup
|
||||
thread.join(1) while thread.alive?
|
||||
expect(thread[:exit_code]).to eq(exit_code)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "#ruby" do
|
||||
|
|
Loading…
Reference in New Issue