ztk 1.16.2 → 1.17.0
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 +8 -8
- data/lib/ztk/parallel.rb +67 -1
- data/lib/ztk/version.rb +1 -1
- data/spec/ztk/parallel_spec.rb +25 -2
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
YzBhZGNmNmVjYzgxMzk1MWI4MTBmMzE2ZTViMjVjYmY1NGUzMDc3ZA==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
ZGFkMjAxZGVmNDg3ZjRkODI0OWIxMTRhODA2ZmMzNDlhNTgzOGQyMQ==
|
7
7
|
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
YjQzNDdkYzQxYmZlOGYzNWViZjRkZTlmODQ2MWE3MDcxNTdjZmQ1MWEzODg4
|
10
|
+
ZDU4ODI3MWZjYTA0NDlhODIyMjEwMjY1ZWRlOThhZDg4YmI3YmM2YWRjZDVh
|
11
|
+
YWE5NzU0ZGQzNTU0ZGYxMzU2NjQ4MTRjYmZmYWZkYmZjNmI5M2U=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
MzFlYzc2NDVlYTkxN2Y1NTNmMzk1ODdmMzMzZThjOWIwMzM1MTdiZDYzMzI2
|
14
|
+
NDNlYmQxN2E3ZmRkNjdjYzVlMjQxMmNlNWQ2YjYxOThjZGZkZmMwMjkzYWJh
|
15
|
+
MGQyMzUwMGNlMDlhOGQxMTdjYTFmZDM0MWU1NTBhMzFkNWQ0Nzc=
|
data/lib/ztk/parallel.rb
CHANGED
@@ -96,6 +96,20 @@ module ZTK
|
|
96
96
|
# @author Zachary Patten <zachary AT jovelabs DOT com>
|
97
97
|
class Parallel < ZTK::Base
|
98
98
|
|
99
|
+
class Break < ParallelError; end
|
100
|
+
|
101
|
+
# Tests if we can marshal an exception via the results; otherwise creates
|
102
|
+
# an exception we can marshal.
|
103
|
+
class ExceptionWrapper
|
104
|
+
attr_reader :exception
|
105
|
+
|
106
|
+
def initialize(exception)
|
107
|
+
dumpable = (Marshal.dump(exception) rescue nil)
|
108
|
+
dumpable.nil? and (exception = RuntimeError.new(exception.inspect))
|
109
|
+
@exception = exception
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
99
113
|
# Default Maximum Number of Forks
|
100
114
|
MAX_FORKS = case RUBY_PLATFORM
|
101
115
|
when /darwin/ then
|
@@ -129,6 +143,15 @@ module ZTK
|
|
129
143
|
@forks = Array.new
|
130
144
|
@results = Array.new
|
131
145
|
GC.respond_to?(:copy_on_write_friendly=) and GC.copy_on_write_friendly = true
|
146
|
+
|
147
|
+
%w( kill term int hup ).map(&:upcase).each do |signal|
|
148
|
+
Signal.trap(signal) do
|
149
|
+
$stderr.puts("SIG#{signal} received by PID##{Process.pid}; aborting parallel executing...")
|
150
|
+
|
151
|
+
signal_all(signal)
|
152
|
+
exit!(1)
|
153
|
+
end
|
154
|
+
end
|
132
155
|
end
|
133
156
|
|
134
157
|
# Process in parallel.
|
@@ -151,18 +174,27 @@ module ZTK
|
|
151
174
|
|
152
175
|
config.before_fork and config.before_fork.call(Process.pid)
|
153
176
|
pid = Process.fork do
|
177
|
+
|
154
178
|
config.after_fork and config.after_fork.call(Process.pid)
|
155
179
|
|
156
180
|
parent_writer.close
|
157
181
|
parent_reader.close
|
158
182
|
|
159
|
-
|
183
|
+
data = nil
|
184
|
+
begin
|
185
|
+
data = block.call
|
186
|
+
rescue Exception => e
|
187
|
+
data = ExceptionWrapper.new(e)
|
188
|
+
end
|
189
|
+
|
190
|
+
if !data.nil?
|
160
191
|
config.ui.logger.debug { "write(#{data.inspect})" }
|
161
192
|
child_writer.write(Base64.encode64(Marshal.dump(data)))
|
162
193
|
end
|
163
194
|
|
164
195
|
child_reader.close
|
165
196
|
child_writer.close
|
197
|
+
|
166
198
|
Process.exit!(0)
|
167
199
|
end
|
168
200
|
config.after_fork and config.after_fork.call(Process.pid)
|
@@ -188,10 +220,14 @@ module ZTK
|
|
188
220
|
config.ui.logger.debug { "wait" }
|
189
221
|
config.ui.logger.debug { "forks(#{@forks.inspect})" }
|
190
222
|
pid, status = (Process.wait2(-1) rescue nil)
|
223
|
+
|
191
224
|
if !pid.nil? && !status.nil? && !(fork = @forks.select{ |f| f[:pid] == pid }.first).nil?
|
192
225
|
data = (Marshal.load(Base64.decode64(fork[:reader].read.to_s)) rescue nil)
|
193
226
|
config.ui.logger.debug { "read(#{data.inspect})" }
|
227
|
+
|
228
|
+
process_exception_data(data)
|
194
229
|
!data.nil? and @results.push(data)
|
230
|
+
|
195
231
|
fork[:reader].close
|
196
232
|
fork[:writer].close
|
197
233
|
|
@@ -212,6 +248,24 @@ module ZTK
|
|
212
248
|
@results
|
213
249
|
end
|
214
250
|
|
251
|
+
# Signals all forks.
|
252
|
+
#
|
253
|
+
# @return [Integer] The number of processes signaled.
|
254
|
+
def signal_all(signal="KILL")
|
255
|
+
signaled = 0
|
256
|
+
if (!@forks.nil? && (@forks.count > 0))
|
257
|
+
@forks.each do |fork|
|
258
|
+
begin
|
259
|
+
Process.kill(signal, fork[:pid])
|
260
|
+
signaled += 1
|
261
|
+
rescue
|
262
|
+
nil
|
263
|
+
end
|
264
|
+
end
|
265
|
+
end
|
266
|
+
signaled
|
267
|
+
end
|
268
|
+
|
215
269
|
# Count of active forks.
|
216
270
|
#
|
217
271
|
# @return [Integer] Current number of active forks.
|
@@ -220,6 +274,18 @@ module ZTK
|
|
220
274
|
@forks.count
|
221
275
|
end
|
222
276
|
|
277
|
+
|
278
|
+
private
|
279
|
+
|
280
|
+
def process_exception_data(data)
|
281
|
+
return if !(ZTK::Parallel::ExceptionWrapper === data)
|
282
|
+
|
283
|
+
config.ui.logger.fatal { "exception(#{data.exception.inspect})" }
|
284
|
+
|
285
|
+
signal_all
|
286
|
+
raise data.exception
|
287
|
+
end
|
288
|
+
|
223
289
|
end
|
224
290
|
|
225
291
|
end
|
data/lib/ztk/version.rb
CHANGED
data/spec/ztk/parallel_spec.rb
CHANGED
@@ -22,7 +22,10 @@ require "spec_helper"
|
|
22
22
|
|
23
23
|
describe ZTK::Parallel do
|
24
24
|
|
25
|
-
subject {
|
25
|
+
subject {
|
26
|
+
ui = ZTK::UI.new(:logger => $logger)
|
27
|
+
ZTK::Parallel.new(:ui => ui)
|
28
|
+
}
|
26
29
|
|
27
30
|
describe "class" do
|
28
31
|
|
@@ -56,6 +59,26 @@ describe ZTK::Parallel do
|
|
56
59
|
subject.results.include?(Process.pid).should be false
|
57
60
|
end
|
58
61
|
|
62
|
+
it "should stop all execution when the ZTK::Parallel::Break exception is raised" do
|
63
|
+
3.times do |x|
|
64
|
+
subject.process do
|
65
|
+
raise ZTK::Parallel::Break
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
lambda { subject.waitall }.should raise_error
|
70
|
+
end
|
71
|
+
|
72
|
+
it "should stop all execution when any exception is raised" do
|
73
|
+
3.times do |x|
|
74
|
+
subject.process do
|
75
|
+
raise "SomeException"
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
lambda { subject.waitall }.should raise_error
|
80
|
+
end
|
81
|
+
|
59
82
|
end
|
60
83
|
|
61
84
|
describe "#wait" do
|
@@ -67,7 +90,7 @@ describe ZTK::Parallel do
|
|
67
90
|
end
|
68
91
|
end
|
69
92
|
|
70
|
-
|
93
|
+
while subject.count > 0 do
|
71
94
|
subject.wait
|
72
95
|
end
|
73
96
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ztk
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.17.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Zachary Patten
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-02-
|
11
|
+
date: 2014-02-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|