kommando 0.0.16 → 0.0.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ea4177fe69b2dda93641ad54157d9c917cbcd322
4
- data.tar.gz: a2c071b228bc3c5b48749d42a5fd5af0be41e2b1
3
+ metadata.gz: 9003ef03825d24dbed6e95661acc172cae3509a7
4
+ data.tar.gz: abc099820ae559c3c69554c632e8a81e3c0b017b
5
5
  SHA512:
6
- metadata.gz: d52dc37e74ee347302f53a8f320898eb2470afe68588cd67988544142286928b0bf8f880e3a21302c2a7c41f61faf80e53a512caaad0fd244f2af93e98aa0362
7
- data.tar.gz: 2aaff338413e4dedbe9ecd44e3c5507e24a24e8274e38de22ff2ba82ddc967a6b230fa1a833723ba5fac0fa5eec3d59bebe5ff7a19663f8b31b0e5afb6c0fed7
6
+ metadata.gz: 004d3ec64ecee487262b169b10421ec753965d96db4580e837d090ea8678bf0fe39d40f15ad876fd5e0076e11f36fecb66f6b3e02deba12dc8c49c82e300a768
7
+ data.tar.gz: 6f81c0dff25c9e21bfd0ddb15f14575c630936ce4d5e42c2c942660f5dc3e9b4e818832ebee7c66b40be10d85450aca4afab4a0db51523482d9dbc08e92f3e6a
data/CHANGELOG.md CHANGED
@@ -1,5 +1,12 @@
1
1
  # CHANGELOG
2
2
 
3
+ ## 0.0.17
4
+ Fixes race condition and reduces the number of threads Kommando creates.
5
+
6
+ - FIX: Race condition when accessing stdout.
7
+ - FIX: Do not start thousands of threads with timeout (above)
8
+ - FIX: More reliable exit status
9
+
3
10
  ## 0.0.16
4
11
  Error callback, optional retry running.
5
12
 
data/bin/release CHANGED
@@ -9,7 +9,7 @@ set -e
9
9
 
10
10
  rake; rake; rake
11
11
  bin/e2e
12
- bin/stress 2 10
12
+ #bin/stress 2 10
13
13
 
14
14
  echo
15
15
  head CHANGELOG.md
data/lib/kommando.rb CHANGED
@@ -28,6 +28,8 @@ class Kommando
28
28
  end
29
29
 
30
30
  def initialize(cmd, opts={})
31
+ Thread.abort_on_exception=true
32
+
31
33
  @cmd = cmd
32
34
  @stdout = Buffer.new
33
35
  @stdin = Buffer.new
@@ -82,10 +84,20 @@ class Kommando
82
84
  end
83
85
 
84
86
  def kill
85
- Process.kill('KILL', @pid)
86
- @kill_happened = true
87
+ begin
88
+ Process.kill('KILL', @pid)
89
+ rescue Errno::ESRCH => ex
90
+ raise ex # see if happens
91
+ end
87
92
 
88
- sleep 0.001 until @code # let finalize
93
+ @kill_happened = true
94
+ begin
95
+ Timeout.timeout(1) do
96
+ sleep 0.001 until @code # let finalize
97
+ end
98
+ rescue Timeout::Error => ex
99
+ raise ex # let's see if happens
100
+ end
89
101
  end
90
102
 
91
103
  def run
@@ -140,43 +152,6 @@ class Kommando
140
152
  stdout_file.sync = true
141
153
  end
142
154
 
143
- Thread.abort_on_exception = true
144
- thread_stdout = Thread.new do
145
- while true do
146
- begin
147
- break if stdout.eof?
148
- rescue Errno::EIO
149
- # Linux http://stackoverflow.com/a/7263243
150
- break
151
- end
152
-
153
- c = nil
154
- begin
155
- Timeout.timeout(0.1) do
156
- c = stdout.getc
157
- end
158
- rescue Timeout::Error
159
- # sometimes it just hangs.
160
- end
161
-
162
- @stdout.append c if c
163
- print c if @output_stdout
164
- stdout_file.write c if @output_file
165
-
166
- if c
167
- @matcher_buffer << c
168
-
169
- matchers_copy = @matchers.clone # blocks can insert to @matchers while iteration is undergoing
170
- matchers_copy.each_pair do |matcher,block|
171
- if @matcher_buffer.match matcher
172
- block.call
173
- @matchers.delete matcher # do not match again TODO: is this safe?
174
- end
175
- end
176
- end
177
- end
178
- end
179
-
180
155
  thread_stdin = Thread.new do
181
156
  sleep 0.1 # allow program to start, do not write "in terminal"
182
157
  while true do
@@ -195,35 +170,19 @@ class Kommando
195
170
  if @timeout
196
171
  begin
197
172
  Timeout.timeout(@timeout) do
198
- thread_stdout.join
173
+ process_stdout(stdout, stdout_file)
199
174
  end
200
175
  rescue Timeout::Error
201
176
  Process.kill('KILL', pid)
202
177
  @timeout_happened = true
203
178
  end
204
179
  else
205
- thread_stdout.join
180
+ process_stdout(stdout, stdout_file)
206
181
  end
207
182
 
208
183
  stdout_file.close if @output_file
209
184
  end
210
185
 
211
- @code = if @timeout_happened
212
- 1
213
- elsif @kill_happened
214
- 137
215
- else
216
- unless $?
217
- begin
218
- Timeout.timeout(0.1) do
219
- Process.wait #WIP: trying to fix weird linux stuff when $? is nil
220
- end
221
- rescue Timeout::Error
222
- end
223
- end
224
-
225
- $?.exitstatus
226
- end
227
186
  rescue RuntimeError => ex
228
187
  if ex.message == "can't get Master/Slave device"
229
188
  #suppress, weird stuff.
@@ -249,6 +208,24 @@ class Kommando
249
208
  @when.fire :error
250
209
  raise Kommando::Error, "Command '#{command}' not found"
251
210
  ensure
211
+ @code = if @timeout_happened
212
+ 1
213
+ elsif @kill_happened
214
+ 137
215
+ else
216
+ begin
217
+ Timeout.timeout(0.1) do
218
+ Process.wait @pid if @pid
219
+ end
220
+ rescue Errno::ECHILD => ex
221
+ # safe to supress, I guess
222
+ rescue Timeout::Error => ex
223
+ # seems to be okay...
224
+ end
225
+
226
+ $?.exitstatus
227
+ end
228
+
252
229
  @when.fire :error if @rescue_happened
253
230
  end
254
231
 
@@ -301,4 +278,36 @@ class Kommando
301
278
  def make_pty_testable
302
279
  PTY
303
280
  end
281
+
282
+ def process_stdout(stdout, stdout_file)
283
+ while true do
284
+ begin
285
+ break if stdout.eof?
286
+ rescue Errno::EIO
287
+ # Linux http://stackoverflow.com/a/7263243
288
+ break
289
+ end
290
+
291
+ c = stdout.getc
292
+
293
+ next unless c
294
+
295
+ @stdout.append c if c
296
+ print c if @output_stdout
297
+ stdout_file.write c if @output_file
298
+
299
+ if c
300
+ @matcher_buffer << c
301
+
302
+ matchers_copy = @matchers.clone # blocks can insert to @matchers while iteration is undergoing
303
+ matchers_copy.each_pair do |matcher,block|
304
+ if @matcher_buffer.match matcher
305
+ block.call
306
+ @matchers.delete matcher # do not match again TODO: is this safe?
307
+ end
308
+ end
309
+ end
310
+ end
311
+ end
312
+
304
313
  end
@@ -1,3 +1,3 @@
1
1
  class Kommando
2
- VERSION = "0.0.16"
2
+ VERSION = "0.0.17"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kommando
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.16
4
+ version: 0.0.17
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matti Paksula