Class: ProcessExecuter::Result

Inherits:
SimpleDelegator
  • Object
show all
Defined in:
lib/process_executer/result.rb

Overview

A decorator for Process::Status that adds the following attributes:

  • command: the command that was used to spawn the process
  • options: the options that were used to spawn the process
  • elapsed_time: the secs the command ran
  • stdout: the captured stdout output
  • stderr: the captured stderr output
  • timed_out?: true if the process timed out

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(status, command:, options:, timed_out:, elapsed_time:) ⇒ Result

Create a new Result object

Examples:

command = ['sleep 1']
options = ProcessExecuter::Options.new(timeout_after: 0.5)
start_time = Process.clock_gettime(Process::CLOCK_MONOTONIC)
timed_out = false
status = nil
pid = Process.spawn(*command, **options.spawn_options)
Timeout.timeout(options.timeout_after) do
  _pid, status = Process.wait2(pid)
rescue Timeout::Error
  Process.kill('KILL', pid)
  timed_out = true
  _pid, status = Process.wait2(pid)
end
elapsed_time = Process.clock_gettime(Process::CLOCK_MONOTONIC) - start_time

ProcessExecuter::Result.new(status, command:, options:, timed_out:, elapsed_time:)

Parameters:

  • status (Process::Status)

    the status to delegate to

  • command (Array)

    the command that was used to spawn the process

  • options (ProcessExecuter::Options)

    the options that were used to spawn the process

  • timed_out (Boolean)

    true if the process timed out

  • elapsed_time (Numeric)

    the secs the command ran

[View source]

46
47
48
49
50
51
52
# File 'lib/process_executer/result.rb', line 46

def initialize(status, command:, options:, timed_out:, elapsed_time:)
  super(status)
  @command = command
  @options = options
  @timed_out = timed_out
  @elapsed_time = elapsed_time
end

Instance Attribute Details

#commandArray (readonly)

The command that was used to spawn the process

Examples:

result.command #=> [{ 'GIT_DIR' => '/path/to/repo' }, 'git', 'status']

Returns:

  • (Array)

See Also:

  • Process.spawn

59
60
61
# File 'lib/process_executer/result.rb', line 59

def command
  @command
end

#elapsed_timeNumeric? (readonly)

The secs the command ran

Examples:

result.elapsed_time #=> 10

Returns:

  • (Numeric, nil)

74
75
76
# File 'lib/process_executer/result.rb', line 74

def elapsed_time
  @elapsed_time
end

#optionsHash (readonly)

The options that were used to spawn the process

Examples:

result.options #=> { chdir: '/path/to/repo', timeout_after: 0.5 }

Returns:

  • (Hash)

See Also:

  • Process.spawn

67
68
69
# File 'lib/process_executer/result.rb', line 67

def options
  @options
end

#timed_out?Boolean (readonly)

True if the process timed out and was sent the SIGKILL signal

Examples:

result = ProcessExecuter.spawn('sleep 10', timeout_after: 0.01)
result.timed_out? # => true

Returns:

  • (Boolean)

83
84
85
# File 'lib/process_executer/result.rb', line 83

def timed_out?
  @timed_out
end

Instance Method Details

#stderrString?

Return the captured stderr output

This output is only returned if the :err option value is a ProcessExecuter::MonitoredPipe.

Examples:

# Note that `ProcessExecuter.run` will wrap the given err: object in a
# ProcessExecuter::MonitoredPipe
result = ProcessExecuter.run('echo ERROR 1>&2', err: StringIO.new)
resuilt.stderr #=> "ERROR\n"

Returns:

  • (String, nil)
[View source]

143
144
145
146
147
148
# File 'lib/process_executer/result.rb', line 143

def stderr
  pipe = options.stderr_redirection_value
  return nil unless pipe.is_a?(ProcessExecuter::MonitoredPipe)

  pipe.destination.string
end

#stdoutString?

Return the captured stdout output

This output is only returned if the :out option value is a ProcessExecuter::MonitoredPipe.

Examples:

# Note that `ProcessExecuter.run` will wrap the given out: object in a
# ProcessExecuter::MonitoredPipe
result = ProcessExecuter.run('echo hello': out: StringIO.new)
result.stdout #=> "hello\n"

Returns:

  • (String, nil)
[View source]

123
124
125
126
127
128
# File 'lib/process_executer/result.rb', line 123

def stdout
  pipe = options.stdout_redirection_value
  return nil unless pipe.is_a?(ProcessExecuter::MonitoredPipe)

  pipe.destination.string
end

#success?true?

Overrides the default success? method to return nil if the process timed out

This is because when a timeout occurs, Windows will still return true.

Examples:

result = ProcessExecuter.spawn('sleep 10', timeout_after: 0.01)
result.success? # => nil

Returns:

  • (true, nil)
[View source]

96
97
98
99
100
# File 'lib/process_executer/result.rb', line 96

def success?
  return nil if timed_out? # rubocop:disable Style/ReturnNilInPredicateMethodDefinition

  super
end

#to_sString

Return a string representation of the result

Examples:

result.to_s #=> "pid 70144 SIGKILL (signal 9) timed out after 10s"

Returns:

  • (String)
[View source]

106
107
108
# File 'lib/process_executer/result.rb', line 106

def to_s
  "#{super}#{timed_out? ? " timed out after #{options.timeout_after}s" : ''}"
end