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 +4 -4
- data/CHANGELOG.md +7 -0
- data/bin/release +1 -1
- data/lib/kommando.rb +67 -58
- data/lib/kommando/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9003ef03825d24dbed6e95661acc172cae3509a7
|
4
|
+
data.tar.gz: abc099820ae559c3c69554c632e8a81e3c0b017b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
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
|
-
|
86
|
-
|
87
|
+
begin
|
88
|
+
Process.kill('KILL', @pid)
|
89
|
+
rescue Errno::ESRCH => ex
|
90
|
+
raise ex # see if happens
|
91
|
+
end
|
87
92
|
|
88
|
-
|
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
|
-
|
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
|
-
|
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
|
data/lib/kommando/version.rb
CHANGED