class Aruba::Processes::SpawnProcess
Spawn a process for command
`SpawnProcess` is not meant for direct use - `SpawnProcess.new` - by users. Only it's public methods are part of the public API of aruba, e.g. `#stdin`, `#stdout`.
@private
Public Class Methods
Use as default launcher
# File lib/aruba/processes/spawn_process.rb, line 22 def self.match?(mode) true end
Create process
@param [String] cmd
Command string
@param [Numeric] exit_timeout
The timeout until we expect the command to be finished
@param [Numeric] io_wait_timeout
The timeout until we expect the io to be finished
@param [String] working_directory
The directory where the command will be executed
@param [Hash] environment
Environment variables
@param [Class] main_class
E.g. Cli::App::Runner
@param [String] stop_signal
Name of signal to send to stop process. E.g. 'HUP'.
@param [Numeric] startup_wait_time
The amount of seconds to wait after Aruba has started a command.
Aruba::Processes::BasicProcess::new
# File lib/aruba/processes/spawn_process.rb, line 51 def initialize(cmd, exit_timeout, io_wait_timeout, working_directory, environment = ENV.to_hash.dup, main_class = nil, stop_signal = nil, startup_wait_time = 0) super @process = nil @stdout_cache = nil @stderr_cache = nil end
Public Instance Methods
Close io
# File lib/aruba/processes/spawn_process.rb, line 175 def close_io(name) return if stopped? if RUBY_VERSION < '1.9' @process.io.send(name.to_sym).close else @process.io.public_send(name.to_sym).close end end
Content of command
@return [String]
The content of the script/command. This might be binary output as string if your command is a binary executable.
# File lib/aruba/processes/spawn_process.rb, line 263 def content File.read command_string.to_s end
Return file system stats for the given command
@return [Aruba::Platforms::FilesystemStatus]
This returns a File::Stat-object
# File lib/aruba/processes/spawn_process.rb, line 254 def filesystem_status Aruba.platform.filesystem_status.new(command_string.to_s) end
Output pid of process
This is the PID of the spawned process.
# File lib/aruba/processes/spawn_process.rb, line 234 def pid @process.pid end
# File lib/aruba/processes/spawn_process.rb, line 157 def read_stdout # rubocop:disable Metrics/LineLength Aruba.platform.deprecated('The use of "#read_stdout" is deprecated. Use "#stdout" instead. To reduce the time to wait for io, pass `:wait_for_io => 0` or some suitable for your use case') # rubocop:enable Metrics/LineLength stdout(:wait_for_io => 0) end
Send command a signal
@param [String] signal
The signal, i.e. 'TERM'
# File lib/aruba/processes/spawn_process.rb, line 242 def send_signal(signal) fail CommandAlreadyStoppedError, %(Command "#{commandline}" with PID "#{pid}" has already stopped.) if @process.exited? Process.kill signal, pid rescue Errno::ESRCH raise CommandAlreadyStoppedError, %(Command "#{commandline}" with PID "#{pid}" has already stopped.) end
Run the command
@yield [SpawnProcess]
Run code for process which was started
rubocop:disable Metrics/MethodLength
# File lib/aruba/processes/spawn_process.rb, line 65 def start # rubocop:disable Metrics/LineLength fail CommandAlreadyStartedError, %(Command "#{commandline}" has already been started. Please `#stop` the command first and `#start` it again. Alternatively use `#restart`.\n#{caller.join("\n")}) if started? # rubocop:enable Metrics/LineLength @started = true @process = ChildProcess.build(*[command_string.to_a, arguments].flatten) @stdout_file = Tempfile.new('aruba-stdout-') @stderr_file = Tempfile.new('aruba-stderr-') @stdout_file.sync = true @stderr_file.sync = true if RUBY_VERSION >= '1.9' @stdout_file.set_encoding('ASCII-8BIT') @stderr_file.set_encoding('ASCII-8BIT') end @exit_status = nil @duplex = true before_run @process.leader = true @process.io.stdout = @stdout_file @process.io.stderr = @stderr_file @process.duplex = @duplex @process.cwd = @working_directory @process.environment.update(environment) begin Aruba.platform.with_environment(environment) do @process.start sleep startup_wait_time end rescue ChildProcess::LaunchError => e raise LaunchError, "It tried to start #{cmd}. " + e.message end after_run yield self if block_given? end
Access to stderr of process
@param [Hash] opts
Options
@option [Integer] wait_for_io
Wait for IO to be finished
@return [String]
The content of stderr
# File lib/aruba/processes/spawn_process.rb, line 148 def stderr(opts = {}) return @stderr_cache if stopped? wait_for_io opts.fetch(:wait_for_io, io_wait_timeout) do @process.io.stderr.flush open(@stderr_file.path).read end end
Access to stdin of process
# File lib/aruba/processes/spawn_process.rb, line 113 def stdin return if @process.exited? @process.io.stdin end
Access to stdout of process
@param [Hash] opts
Options
@option [Integer] wait_for_io
Wait for IO to be finished
@return [String]
The content of stdout
# File lib/aruba/processes/spawn_process.rb, line 129 def stdout(opts = {}) return @stdout_cache if stopped? wait_for_io opts.fetch(:wait_for_io, io_wait_timeout) do @process.io.stdout.flush open(@stdout_file.path).read end end
Stop command
# File lib/aruba/processes/spawn_process.rb, line 186 def stop(*) return @exit_status if stopped? begin @process.poll_for_exit(@exit_timeout) rescue ChildProcess::TimeoutError @timed_out = true end terminate end
Terminate command
# File lib/aruba/processes/spawn_process.rb, line 204 def terminate return @exit_status if stopped? unless @process.exited? if @stop_signal # send stop signal ... send_signal @stop_signal # ... and set the exit status wait else @process.stop end end @exit_status = @process.exit_code @stdout_cache = read_temporary_output_file @stdout_file @stderr_cache = read_temporary_output_file @stderr_file # @stdout_file = nil # @stderr_file = nil @started = false @exit_status end
Wait for command to finish
# File lib/aruba/processes/spawn_process.rb, line 199 def wait @process.wait end
# File lib/aruba/processes/spawn_process.rb, line 165 def write(input) return if stopped? @process.io.stdin.write(input) @process.io.stdin.flush self end
Private Instance Methods
# File lib/aruba/processes/spawn_process.rb, line 269 def command_string # gather fully qualified path cmd = Aruba.platform.which(command, environment['PATH']) fail LaunchError, %(Command "#{command}" not found in PATH-variable "#{environment['PATH']}".) if cmd.nil? Aruba.platform.command_string.new(cmd) end
# File lib/aruba/processes/spawn_process.rb, line 283 def read_temporary_output_file(file) file.flush file.rewind data = file.read file.close if RUBY_VERSION >= '1.9' data.force_encoding('UTF-8') else data end end
# File lib/aruba/processes/spawn_process.rb, line 278 def wait_for_io(time_to_wait, &block) sleep time_to_wait yield end