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 CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- YzM4ZjAxYThhZjBkZDc2NTQ3MDhjYTlmYmYwYjUzNGIzMmQ4ZmIwYw==
4
+ YzBhZGNmNmVjYzgxMzk1MWI4MTBmMzE2ZTViMjVjYmY1NGUzMDc3ZA==
5
5
  data.tar.gz: !binary |-
6
- NDllOTBjMjdjNzc2ZWVkYWE1Yzk5ODA3YWNkMzMzOTI1YTRlY2I0MQ==
6
+ ZGFkMjAxZGVmNDg3ZjRkODI0OWIxMTRhODA2ZmMzNDlhNTgzOGQyMQ==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- YmJkNzI3NzFlMWNhNmNlMGIzNzM2NTcwYzc1OTIxZGQzMTcxZjUzNTk1MWVl
10
- ZTFhNzI5Mjc5MTFjOTkxODUyZGY3NWNjODg5NTU2YzBlNmNiZWRlZWM5ZDgx
11
- MmNmMDZiM2Q1ZTYxMzIzOTVhMmE1MDQ3ZDMyMmUwMTc3MjFmZDA=
9
+ YjQzNDdkYzQxYmZlOGYzNWViZjRkZTlmODQ2MWE3MDcxNTdjZmQ1MWEzODg4
10
+ ZDU4ODI3MWZjYTA0NDlhODIyMjEwMjY1ZWRlOThhZDg4YmI3YmM2YWRjZDVh
11
+ YWE5NzU0ZGQzNTU0ZGYxMzU2NjQ4MTRjYmZmYWZkYmZjNmI5M2U=
12
12
  data.tar.gz: !binary |-
13
- NDM3YjEwODQ0ZWRmMGZkYTU2N2ZjMWNjZTc5ZmU5NGY3NTU4YzFhMTFjY2Nm
14
- ODk4MTZiNWYxYjhjZjIwZWQxMDQyYmNlZmRiZTM1M2EzY2JhZWU1OTY2Mzdi
15
- NjUwNWRjMmNmMjZmNTZhMzIwZWIyMTY2OTI1ZWZjYjhmZjMyZjM=
13
+ MzFlYzc2NDVlYTkxN2Y1NTNmMzk1ODdmMzMzZThjOWIwMzM1MTdiZDYzMzI2
14
+ NDNlYmQxN2E3ZmRkNjdjYzVlMjQxMmNlNWQ2YjYxOThjZGZkZmMwMjkzYWJh
15
+ MGQyMzUwMGNlMDlhOGQxMTdjYTFmZDM0MWU1NTBhMzFkNWQ0Nzc=
@@ -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
- if !(data = block.call).nil?
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
@@ -1,6 +1,6 @@
1
1
  module ZTK
2
2
 
3
3
  # ZTK Version String
4
- VERSION = "1.16.2"
4
+ VERSION = "1.17.0"
5
5
 
6
6
  end
@@ -22,7 +22,10 @@ require "spec_helper"
22
22
 
23
23
  describe ZTK::Parallel do
24
24
 
25
- subject { ZTK::Parallel.new }
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
- 3.times do
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.16.2
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-03 00:00:00.000000000 Z
11
+ date: 2014-02-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport