Require what to be notified for with block and Subprocess.execute
There was an issue before where the stdin buffer would always have space so it would always yield that block and Ruby would spin at 100%. Now we require all callers to say what they want to listen for. This drops CPU down to almost nothing. See GH-832
This commit is contained in:
parent
903fd3acdc
commit
1a6ae81aa9
|
@ -314,6 +314,9 @@ module Vagrant
|
|||
@logger.info("Interrupted.")
|
||||
end
|
||||
|
||||
# Append in the options for subprocess
|
||||
command << { :notify => [:stdout, :stderr] }
|
||||
|
||||
Util::Busy.busy(int_callback) do
|
||||
Subprocess.execute(@vboxmanage_path, *command, &block)
|
||||
end
|
||||
|
|
|
@ -63,7 +63,7 @@ module Vagrant
|
|||
end
|
||||
end
|
||||
|
||||
Vagrant::Util::Subprocess.execute(command, &block)
|
||||
Vagrant::Util::Subprocess.execute(command, :notify => [:stdout, :stderr], &block)
|
||||
end
|
||||
|
||||
# Run a shell command within the VM. The command will run within a
|
||||
|
|
|
@ -29,8 +29,27 @@ module Vagrant
|
|||
def execute
|
||||
# Get the timeout, if we have one
|
||||
timeout = @options[:timeout]
|
||||
|
||||
# Get the working directory
|
||||
workdir = @options[:workdir] || Dir.pwd
|
||||
|
||||
# Get what we're interested in being notified about
|
||||
notify = @options[:notify] || []
|
||||
notify = [notify] if !notify.is_a?(Array)
|
||||
if notify.empty? && block_given?
|
||||
# If a block is given, subscribers must be given, otherwise the
|
||||
# block is never called. This is usually NOT what you want, so this
|
||||
# is an error.
|
||||
message = "A list of notify subscriptions must be given if a block is given"
|
||||
raise ArgumentError, message
|
||||
end
|
||||
|
||||
# Let's get some more useful booleans that we access a lot so
|
||||
# we're not constantly calling an `include` check
|
||||
notify_stderr = notify.include?(:stderr)
|
||||
notify_stdin = notify.include?(:stdin)
|
||||
notify_stdout = notify.include?(:stdout)
|
||||
|
||||
# Build the ChildProcess
|
||||
@logger.info("Starting process: #{@command.inspect}")
|
||||
process = ChildProcess.build(*@command)
|
||||
|
@ -80,7 +99,8 @@ module Vagrant
|
|||
|
||||
@logger.debug("Selecting on IO")
|
||||
while true
|
||||
results = IO.select([stdout, stderr], [process.io.stdin], nil, timeout || 5)
|
||||
writers = notify_stdin ? [process.io.stdin] : []
|
||||
results = IO.select([stdout, stderr], writers, nil, timeout || 5)
|
||||
readers, writers = results
|
||||
|
||||
# Check if we have exceeded our timeout
|
||||
|
|
|
@ -51,7 +51,8 @@ module Acceptance
|
|||
options = argN.last.is_a?(Hash) ? argN.pop : {}
|
||||
options = {
|
||||
:workdir => @workdir,
|
||||
:env => @env
|
||||
:env => @env,
|
||||
:notify => [:stdin, :stderr, :stdout]
|
||||
}.merge(options)
|
||||
|
||||
# Add the options to be passed on
|
||||
|
@ -59,7 +60,7 @@ module Acceptance
|
|||
|
||||
# Execute, logging out the stdout/stderr as we get it
|
||||
@logger.info("Executing: #{[command].concat(argN).inspect}")
|
||||
Vagrant::Util::Subprocess.execute(command, *argN) do |type, data|
|
||||
Vagrant::Util::Subprocess.execute(command *argN) do |type, data|
|
||||
@logger.debug("#{type}: #{data}") if type == :stdout || type == :stderr
|
||||
yield type, data if block_given?
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue