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