parallelize 0.3.0 → 0.4.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.
data/CHANGELOG.rdoc CHANGED
@@ -1,3 +1,6 @@
1
+ === 0.4.0 / 2012/06/19
2
+ * Added interrupt handling
3
+
1
4
  === 0.3.0 / 2012/06/10
2
5
  * Added `pmap`
3
6
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.3.0
1
+ 0.4.0
@@ -5,40 +5,62 @@ module Enumerable
5
5
  raise ArgumentError.new("Invalid number of threads") if num_threads < 1
6
6
 
7
7
  threads = []
8
- enum.each_slice((enum.count{true} / num_threads.to_f).ceil) do |slice|
9
- threads <<
10
- case block.arity
11
- when 2
12
- Thread.new(slice, threads.length) { |my_slice, thread_idx|
13
- my_slice.send(method) { |e| yield e, thread_idx }
14
- }
15
- when 1
16
- Thread.new(slice) { |my_slice|
17
- my_slice.send(method) { |e| yield e }
18
- }
19
- when 0, -1
20
- raise ArgumentError.new("Invalid arity: #{block.arity}") if
21
- RUBY_VERSION !~ /^1.8\./ && block.arity == -1
22
- Thread.new(slice) { |my_slice|
23
- my_slice.send(method) { yield }
24
- }
25
- else
26
- raise ArgumentError.new("Invalid arity: #{block.arity}")
8
+
9
+ reap = lambda do |tidx|
10
+ threads[tidx..-1].each do |t|
11
+ t.raise Interrupt if t.alive?
12
+ begin
13
+ t.join
14
+ rescue Exception
15
+ nil
27
16
  end
17
+ end
28
18
  end
29
19
 
30
- exceptions = {}
31
- threads.each_with_index do |thr, idx|
32
- begin
33
- thr.join
34
- rescue Exception => e
35
- if collect_exceptions
36
- exceptions[idx] = e
37
- nil
38
- else
39
- raise e
20
+ begin
21
+ prev_trap = trap('INT') { Thread.current.raise Interrupt }
22
+ enum.each_slice((enum.count{true} / num_threads.to_f).ceil) do |slice|
23
+ threads <<
24
+ case block.arity
25
+ when 2
26
+ Thread.new(slice, threads.length) { |my_slice, thread_idx|
27
+ my_slice.send(method) { |e| yield e, thread_idx }
28
+ }
29
+ when 1
30
+ Thread.new(slice) { |my_slice|
31
+ my_slice.send(method) { |e| yield e }
32
+ }
33
+ when 0, -1
34
+ raise ArgumentError.new("Invalid arity: #{block.arity}") if
35
+ RUBY_VERSION !~ /^1.8\./ && block.arity == -1
36
+ Thread.new(slice) { |my_slice|
37
+ my_slice.send(method) { yield }
38
+ }
39
+ else
40
+ raise ArgumentError.new("Invalid arity: #{block.arity}")
41
+ end
42
+ end
43
+
44
+ exceptions = {}
45
+ threads.each_with_index do |thr, idx|
46
+ begin
47
+ thr.join
48
+ rescue Exception => e
49
+ if collect_exceptions
50
+ exceptions[idx] = e
51
+ nil
52
+ else
53
+ reap.call idx + 1
54
+ raise e
55
+ end
40
56
  end
41
57
  end
58
+ rescue Interrupt
59
+ # Interrupts threads
60
+ reap.call 0
61
+ raise
62
+ ensure
63
+ trap('INT', prev_trap) if prev_trap
42
64
  end
43
65
 
44
66
  unless exceptions.empty?
@@ -137,4 +137,54 @@ class TestParallelize < Test::Unit::TestCase
137
137
  (0..100).pmap(thr) { |e, tidx| "#{e} by #{tidx}" }
138
138
  )
139
139
  end
140
+
141
+ def test_reap
142
+ ic = 0
143
+ t = Thread.new {
144
+ begin
145
+ parallelize(2) do |idx|
146
+ begin
147
+ raise Exception.new if idx == 0
148
+ loop {}
149
+ rescue Interrupt
150
+ puts "Interrupted (#{idx}-#{ic})"
151
+ ic += 1
152
+ end
153
+ end
154
+ rescue Interrupt
155
+ puts "Interrupted (parallelize-#{ic})"
156
+ ic += 1
157
+ rescue Exception
158
+ puts "Exception thrown from a child"
159
+ raise
160
+ end
161
+ }
162
+
163
+ assert_raise(Exception) { t.join }
164
+ assert_equal 1, ic
165
+ end
166
+
167
+ def test_interrupt
168
+ ic = 0
169
+ t = Thread.new {
170
+ begin
171
+ parallelize(2) do |idx|
172
+ begin
173
+ loop {}
174
+ rescue Interrupt
175
+ puts "Interrupted (#{idx}-#{ic})"
176
+ ic += 1
177
+ end
178
+ end
179
+ rescue Interrupt
180
+ puts "Interrupted (parallelize-#{ic})"
181
+ ic += 1
182
+ end
183
+ }
184
+
185
+ sleep 2
186
+ t.raise Interrupt
187
+ t.join
188
+ assert_equal 3, ic
189
+ end
140
190
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: parallelize
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.4.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-06-10 00:00:00.000000000 Z
12
+ date: 2012-06-19 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: yard
@@ -81,7 +81,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
81
81
  version: '0'
82
82
  segments:
83
83
  - 0
84
- hash: 4037532998974082938
84
+ hash: -3400073306691178831
85
85
  required_rubygems_version: !ruby/object:Gem::Requirement
86
86
  none: false
87
87
  requirements: