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
Instance Attribute Summary collapse
-
#progress ⇒ Object
readonly
- Float
-
Get the mesured progress in percentage.
-
#tms ⇒ Object
readonly
- Benchmark::Tms
-
The time mesured of execution in the runner thread.
Class Method Summary collapse
Instance Method Summary collapse
-
#initialize(command, opts = {}) {|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 ⇒ Object
Old get the time really spend (‘real’ part of ‘time` command) DEPRECATED: use tms.real access now.
-
#time_sys ⇒ Object
Get the total time spent in system space (sum of tms.cstime + tms.stime).
-
#time_user ⇒ Object
Get the total time spent in user space (sum of tms.cutime + tms.utime).
-
#wait ⇒ Process::Status
Wait and return the process exit status.
Constructor Details
#initialize(command, opts = {}) {|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:
39 40 41 42 43 44 45 46 47 |
# File 'lib/long-command-runner/runner.rb', line 39 def initialize(command, opts = {}, &on_input) @command = command @container = nil @launch_lock = Mutex.new @on_input = on_input @progress = 0.0 @tms = nil @do_progress_on = opts[:do_progress_on] || 'stdout' end |
Instance Attribute Details
#progress ⇒ Object (readonly)
- Float
-
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.
22 23 24 |
# File 'lib/long-command-runner/runner.rb', line 22 def progress @progress end |
#tms ⇒ Object (readonly)
- Benchmark::Tms
-
The time mesured of execution in the runner thread.
24 25 26 |
# File 'lib/long-command-runner/runner.rb', line 24 def tms @tms end |
Class Method Details
.dead?(pid) ⇒ Boolean
161 162 163 164 165 166 |
# File 'lib/long-command-runner/runner.rb', line 161 def self.dead?(pid) Process.kill(0, pid) false rescue Errno::ESRCH true end |
.kill_children(signal, pid, children) ⇒ Object
168 169 170 171 172 173 174 175 176 |
# File 'lib/long-command-runner/runner.rb', line 168 def self.kill_children(signal, pid, children) n = Process.kill(signal, pid) sleep 0.1 children.keys.reject { |c_pid| dead? c_pid }.each do |c_pid| # the not dead n += kill_children(signal, c_pid, children[c_pid]) end n end |
Instance Method Details
#kill(signal) ⇒ Integer | nil
Send a signal to the running process.
129 130 131 132 133 134 135 136 |
# File 'lib/long-command-runner/runner.rb', line 129 def kill(signal) return nil if @container.nil? children = @container.children Runner.kill_children(signal, @container.pid, children) rescue Errno::ESRCH nil end |
#launch ⇒ Object
Actually launch the process.
62 63 64 65 66 67 68 69 70 71 72 73 74 75 |
# File 'lib/long-command-runner/runner.rb', line 62 def launch @bench_thread = Thread.new do @tms = Benchmark.measure do @container = Container.new(@command) @container.wait end end Thread.pass while @container.nil? @line_reader = LineReader.new([@container.stdout, @container.stderr]) do |*new_lines| on_newline(*new_lines) end @reader_thr = Thread.new { @line_reader.read } Thread.pass end |
#launched? ⇒ Boolean
Tells if the command has been launched at least once.
57 58 59 |
# File 'lib/long-command-runner/runner.rb', line 57 def launched? !@container.nil? end |
#output(separator = "\n") ⇒ String
Get the output lines as separated lines
83 84 85 |
# File 'lib/long-command-runner/runner.rb', line 83 def output(separator = "\n") @line_reader[0].join(separator) end |
#output_error(separator = "\n") ⇒ String
Get the error output lines as separated lines
93 94 95 |
# File 'lib/long-command-runner/runner.rb', line 93 def output_error(separator = "\n") @line_reader[1].join(separator) end |
#pid ⇒ Integer | nil
Get the pid of the process launched
100 101 102 |
# File 'lib/long-command-runner/runner.rb', line 100 def pid @container.pid end |
#running? ⇒ Boolean
Is the last launched command is still running.
50 51 52 53 54 |
# File 'lib/long-command-runner/runner.rb', line 50 def running? return false if @container.nil? @container.running? end |
#status ⇒ Process:Status | nil
Get the status of the process without blocking.
119 120 121 122 123 |
# File 'lib/long-command-runner/runner.rb', line 119 def status return nil if @container.nil? @container.status end |
#time_real ⇒ Object
Old get the time really spend (‘real’ part of ‘time` command) DEPRECATED: use tms.real access now.
140 141 142 143 144 145 |
# File 'lib/long-command-runner/runner.rb', line 140 def time_real warn '[DEPRECATION] use :tms instead of :time_real' return nil if @tms.nil? @tms.real end |
#time_sys ⇒ Object
Get the total time spent in system space (sum of tms.cstime + tms.stime)
155 156 157 158 159 |
# File 'lib/long-command-runner/runner.rb', line 155 def time_sys return nil if @tms.nil? @tms.cstime + @tms.stime end |
#time_user ⇒ Object
Get the total time spent in user space (sum of tms.cutime + tms.utime)
148 149 150 151 152 |
# File 'lib/long-command-runner/runner.rb', line 148 def time_user return nil if @tms.nil? @tms.cutime + @tms.utime end |
#wait ⇒ Process::Status
Wait and return the process exit status. This method is blocking until the process if finished.
108 109 110 111 112 113 |
# File 'lib/long-command-runner/runner.rb', line 108 def wait @bench_thread.join @reader_thr.join sleep 0.01 until @line_reader.streams.all?(&:eof?) @container.status end |