Class: LCR::Runner
- Inherits:
-
Object
- Object
- LCR::Runner
- Defined in:
- lib/long-command-runner/runner.rb
Overview
This class aims to manage an external process through a parallele excecution thread. This means it will not stop the main thread of your program.
Your process can output a progress indicator of the matching the format of PERCENT_INDICATOR constant.
It is possible to re-launch the same command, the out/err buffers won’t be emptied before running unless asked.
Constant Summary collapse
- PERCENT_INDICATOR =
The constant used to get the percetange of completion of the command.
/(.*\s|^)((\d+)([,.]\d*)?)%.*/.freeze
- TIMES_INDICATORS =
The constant to match a ‘time -p` output:
/\A(real|user|sys)\s+(\d+\.\d\d)\z/.freeze
Instance Attribute Summary collapse
-
#progress ⇒ Object
readonly
Get the mesured progress in percentage.
Instance Method Summary collapse
-
#initialize(command) {|nl_stdout, nl_stderr| ... } ⇒ Runner
constructor
Initializer takes the command as a plain string.
-
#kill(signal) ⇒ Integer | nil
Send a signal to the running process.
-
#launch ⇒ Object
Actually launch the process.
-
#launched? ⇒ Boolean
Tells if the command has been launched at least once.
-
#output(separator = "\n") ⇒ String
Get the output lines as separated lines.
-
#output_error(separator = "\n") ⇒ String
Get the error output lines as separated lines.
-
#pid ⇒ Integer | nil
Get the pid of the process launched.
-
#running? ⇒ Boolean
Is the last launched command is still running.
-
#status ⇒ Process:Status | nil
Get the status of the process without blocking.
-
#time_real ⇒ Float | nil
Get the time really spend (‘real’ part of ‘time` command).
-
#time_sys ⇒ Float | nil
Get the time system space spend (‘sys’ part of ‘time` command).
-
#time_user ⇒ Float | nil
Get the time in user space spend (‘user’ part of ‘time` command).
-
#wait ⇒ Process::Status
Wait and return the process exit status.
Constructor Details
#initialize(command) {|nl_stdout, nl_stderr| ... } ⇒ Runner
Initializer takes the command as a plain string. You can optionaly pass a block that will be called when the command generate outputs:
34 35 36 37 38 39 40 41 |
# File 'lib/long-command-runner/runner.rb', line 34 def initialize(command, &on_input) @command = command @container = nil @launch_lock = Mutex.new @on_input = on_input @progress = 0.0 @times = { real: nil, user: nil, sys: nil } end |
Instance Attribute Details
#progress ⇒ Object (readonly)
Get the mesured progress in percentage. This is just the result of parsing stdout lines with PERCENT_INDICATOR. So this percentage is comming from the thread not this library.
23 24 25 |
# File 'lib/long-command-runner/runner.rb', line 23 def progress @progress end |
Instance Method Details
#kill(signal) ⇒ Integer | nil
Send a signal to the running process.
118 119 120 121 122 123 124 |
# File 'lib/long-command-runner/runner.rb', line 118 def kill(signal) return nil if @container.nil? Process.kill(signal, @container.pid) rescue Errno::ESRCH nil end |
#launch ⇒ Object
Actually launch the process.
56 57 58 59 60 61 62 63 64 65 |
# File 'lib/long-command-runner/runner.rb', line 56 def launch stderr, stderr_in = IO.pipe @container = Container.new("bash -c 'time -p #{@command} 2>&3'", 3 => stderr_in) @line_reader = LineReader.new([@container.stdout, stderr, @container.stderr]) do |*new_lines| on_newline(*new_lines) end @reader_thr = Thread.new { @line_reader.read } stderr_in.close Thread.pass end |
#launched? ⇒ Boolean
Tells if the command has been launched at least once.
51 52 53 |
# File 'lib/long-command-runner/runner.rb', line 51 def launched? !@container.nil? end |
#output(separator = "\n") ⇒ String
Get the output lines as separated lines
73 74 75 |
# File 'lib/long-command-runner/runner.rb', line 73 def output(separator = "\n") @line_reader[0].join(separator) end |
#output_error(separator = "\n") ⇒ String
Get the error output lines as separated lines
83 84 85 |
# File 'lib/long-command-runner/runner.rb', line 83 def output_error(separator = "\n") @line_reader[1].join(separator) end |
#pid ⇒ Integer | nil
Get the pid of the process launched
90 91 92 |
# File 'lib/long-command-runner/runner.rb', line 90 def pid @container.pid end |
#running? ⇒ Boolean
Is the last launched command is still running.
44 45 46 47 48 |
# File 'lib/long-command-runner/runner.rb', line 44 def running? return false if @container.nil? @container.running? end |
#status ⇒ Process:Status | nil
Get the status of the process without blocking.
108 109 110 111 112 |
# File 'lib/long-command-runner/runner.rb', line 108 def status return nil if @container.nil? @container.status end |
#time_real ⇒ Float | nil
Get the time really spend (‘real’ part of ‘time` command)
130 131 132 |
# File 'lib/long-command-runner/runner.rb', line 130 def time_real @times[:real] end |
#time_sys ⇒ Float | nil
Get the time system space spend (‘sys’ part of ‘time` command)
146 147 148 |
# File 'lib/long-command-runner/runner.rb', line 146 def time_sys @times[:sys] end |
#time_user ⇒ Float | nil
Get the time in user space spend (‘user’ part of ‘time` command)
138 139 140 |
# File 'lib/long-command-runner/runner.rb', line 138 def time_user @times[:user] end |
#wait ⇒ Process::Status
Wait and return the process exit status. This method is blocking until the process if finished.
98 99 100 101 102 |
# File 'lib/long-command-runner/runner.rb', line 98 def wait p = @container.wait sleep 0.01 until @line_reader.streams.all?(&:eof?) p end |