long-command-runner 0.1.4 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3f6d2038cb89e937c4338cb47e4e3cbbd63e6df288ce146c56cdedaf9cd4e669
4
- data.tar.gz: 12dae9fedb930a911813dd69aa06efc30d6beda0f70c3a5ed902afd657818923
3
+ metadata.gz: 732ddcf74afb4d4a3f7e5990e4761e4fabbea37824890c98e8cc236c3339a317
4
+ data.tar.gz: 3209440517bcfcb93e020e01a3484e029487af1e61b95e86d932db6c27b30c7e
5
5
  SHA512:
6
- metadata.gz: 66a47ff6f6de3d987b5192aad839b2dccf44c5f132c6066e9430e0b0ea8ef8598bb84644936bf7b7c61c166367493a6b06d8a17ae020104a8c2d85168df24a1c
7
- data.tar.gz: 230c0b1ad2803be4f3b267f6724482715bf4bc8403dbe45d3731aa156289c26dff61e73df93c62913e6aa38a106150c45bf9723773c0ef467c53c2ba1b417294
6
+ metadata.gz: ac8cc65bf6dfc634469ca90d9312183aa17c7ec3d7d6649bddfc505879babbf0adadc503124a384d6fe3d78aa335d2d90e230bdfb7cf1d8670bfae04496efd6e
7
+ data.tar.gz: 004ca4095874c144356593c7ceedef1c8a3983b2f6a5fbf18cfd0da5ca154fac670bc64cc81acf22644a5e5603e47a026fb1231c96b69c0cfdf1bf4644e86f19
data/README.md CHANGED
@@ -12,8 +12,7 @@ the CPU usage and the progression of the program.
12
12
  ## Currently (what we have)
13
13
  - monitoring of the progression of the application through the output of the app
14
14
  (I don't think that we can do better)
15
- - get the real/user/sys time usage of the application by using the output of the `time` `bash` function.
16
- (This make it incompatible with system that doesn't support ouput redirections and bash itself)
15
+ - get the real/user/sys time usage of the application by using the lib Benchmark of ruby.
17
16
 
18
17
  ## v1 goal
19
18
 
@@ -5,6 +5,9 @@ require 'open3'
5
5
  module LCR
6
6
  # This class aims to contain the runing script.
7
7
  class Container
8
+ # The expected Language environment:
9
+ ENVIRONMENT = 'LANGUAGE=en'
10
+
8
11
  # Get the standard input IO of the process.
9
12
  #
10
13
  # @note Be aware that it may be closed by the process (on exit), or by you.
@@ -34,7 +37,8 @@ module LCR
34
37
  # @param [String] command The command to execute.
35
38
  # @param [Hash] opts The option to pass to Open3.popen3.
36
39
  def initialize(command, opts = {})
37
- @stdin, @stdout, @stderr, @wait_thr = Open3.popen3(command, opts)
40
+ safe_command = quote_sanitize(command)
41
+ @stdin, @stdout, @stderr, @wait_thr = Open3.popen3("#{ENVIRONMENT} bash -c \"#{safe_command}\"", opts)
38
42
  end
39
43
 
40
44
  # Is the last launched command is still running.
@@ -64,5 +68,11 @@ module LCR
64
68
  def pid
65
69
  @wait_thr.pid
66
70
  end
71
+
72
+ private
73
+
74
+ def quote_sanitize(cmd)
75
+ cmd.gsub(/(["])/, '\\"')
76
+ end
67
77
  end
68
78
  end
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'open3'
4
+ require 'benchmark'
4
5
 
5
6
  module LCR
6
7
  # This class aims to manage an external process through a parallele excecution thread.
@@ -14,15 +15,11 @@ module LCR
14
15
  class Runner
15
16
  # The constant used to get the percetange of completion of the command.
16
17
  PERCENT_INDICATOR = /(.*\s|^)((\d+)([,.]\d*)?)%.*/.freeze
17
- # The constant to match a `time -p` output:
18
- TIMES_INDICATORS = /\A(real|user|sys)\s+(\d+[\.,]\d\d)\z/.freeze
19
- # The expected Language environment:
20
- ENVIRONMENT = 'LC_ALL=C.UTF-8 LANGUAGE=en'
21
18
 
22
19
  # Get the mesured progress in percentage.
23
20
  # This is just the result of parsing stdout lines with {PERCENT_INDICATOR}.
24
21
  # So this percentage is comming from the thread not this library.
25
- attr_reader :progress
22
+ attr_reader :progress, :tms
26
23
 
27
24
  # Initializer takes the command as a plain string.
28
25
  # You can optionaly pass a block that will be called when the command generate
@@ -39,7 +36,7 @@ module LCR
39
36
  @launch_lock = Mutex.new
40
37
  @on_input = on_input
41
38
  @progress = 0.0
42
- @times = { real: nil, user: nil, sys: nil }
39
+ @tms = nil
43
40
  end
44
41
 
45
42
  # Is the last launched command is still running.
@@ -56,13 +53,17 @@ module LCR
56
53
 
57
54
  # Actually launch the process.
58
55
  def launch
59
- stderr, stderr_in = IO.pipe
60
- @container = Container.new("#{ENVIRONMENT} bash -c 'time -p #{@command} 2>&3'", 3 => stderr_in)
61
- @line_reader = LineReader.new([@container.stdout, stderr, @container.stderr]) do |*new_lines|
56
+ @bench_thread = Thread.new do
57
+ @tms = Benchmark.measure do
58
+ @container = Container.new(@command)
59
+ @container.wait
60
+ end
61
+ end
62
+ Thread.pass while @container.nil?
63
+ @line_reader = LineReader.new([@container.stdout, @container.stderr]) do |*new_lines|
62
64
  on_newline(*new_lines)
63
65
  end
64
66
  @reader_thr = Thread.new { @line_reader.read }
65
- stderr_in.close
66
67
  Thread.pass
67
68
  end
68
69
 
@@ -98,9 +99,10 @@ module LCR
98
99
  #
99
100
  # @return [Process::Status]
100
101
  def wait
101
- p = @container.wait
102
+ @bench_thread.join
103
+ @reader_thr.join
102
104
  sleep 0.01 until @line_reader.streams.all?(&:eof?)
103
- p
105
+ @container.status
104
106
  end
105
107
 
106
108
  # Get the status of the process without blocking.
@@ -125,35 +127,37 @@ module LCR
125
127
  nil
126
128
  end
127
129
 
128
- # Get the time really spend ('real' part of `time` command)
129
- #
130
- # @return [Float | nil] The elapsed seconds (using POSIX.2 standard see `time -p` for more information)
131
- # if the Process isn't finished it return nil.
130
+ # Old get the time really spend ('real' part of `time` command)
131
+ # DEPRECATED: use tms access now.
132
132
  def time_real
133
- @times[:real]
133
+ warn '[DEPRECATION] use :tms instead of :time_real'
134
+ return nil if @tms.nil?
135
+
136
+ @tms.real
134
137
  end
135
138
 
136
- # Get the time in user space spend ('user' part of `time` command)
137
- #
138
- # @return [Float | nil] The elapsed seconds (using POSIX.2 standard see `time -p` for more information)
139
- # if the Process isn't finished it return nil.
139
+ # Old get the time in user space spend ('user' part of `time` command)
140
+ # DEPRECATED: use tms access now.
140
141
  def time_user
141
- @times[:user]
142
+ warn '[DEPRECATION] use :tms instead of :time_user'
143
+ return nil if @tms.nil?
144
+
145
+ @tms.cutime + @tms.utime
142
146
  end
143
147
 
144
- # Get the time system space spend ('sys' part of `time` command)
145
- #
146
- # @return [Float | nil] The elapsed seconds (using POSIX.2 standard see `time -p` for more information)
147
- # if the Process isn't finished it return nil.
148
+ # old get the time system space spend ('sys' part of `time` command)
149
+ # DEPRECATED: use tms access now.
148
150
  def time_sys
149
- @times[:sys]
151
+ warn '[DEPRECATION] use :tms instead of :time_user'
152
+ return nil if @tms.nil?
153
+
154
+ @tms.cstime + @tms.stime
150
155
  end
151
156
 
152
157
  private
153
158
 
154
- def on_newline(nl_stdout, nl_stderr, nl_time)
159
+ def on_newline(nl_stdout, nl_stderr)
155
160
  manage_progress(nl_stdout) unless nl_stdout.nil?
156
- manage_time(nl_time) unless nl_time.nil?
157
161
  @on_input&.call(nl_stdout, nl_stderr)
158
162
  end
159
163
 
@@ -163,12 +167,5 @@ module LCR
163
167
 
164
168
  @progress = match[2].to_f
165
169
  end
166
-
167
- def manage_time(new_line)
168
- match = new_line.match TIMES_INDICATORS
169
- return unless match
170
-
171
- @times[match[1].to_sym] = match[2].to_f
172
- end
173
170
  end
174
171
  end
@@ -2,5 +2,5 @@
2
2
 
3
3
  module LCR
4
4
  # Version of the library.
5
- VERSION = '0.1.4'
5
+ VERSION = '0.2.0'
6
6
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: long-command-runner
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.4
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Roland Laurès
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-05-28 00:00:00.000000000 Z
11
+ date: 2019-06-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: pry