kommando 0.0.16 → 0.0.17

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
  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