parallel 1.2.4 → 1.3.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 +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/lib/parallel.rb +98 -34
- data/lib/parallel/version.rb +1 -1
- metadata +2 -2
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d2df287a5ddf0d25ea8f7ab32b06e9d71046eef8
|
4
|
+
data.tar.gz: f4df68005a7a134922caa0dd7458a5ad48ebb14f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 73b00704981e7a87f6c6448cc80759d4e4bbd62c07bc852c84c81da631480571f7acf1cff261eb72f3c2532cee96fb12670329ac9acf35c4f7c48272834ea875
|
7
|
+
data.tar.gz: e975280dc1eb0825479e03e2d433e89021ec336a4bc1ab3e05319afccf73d3c67f190938df1a3faeb5c9c8d1335a0ac64b67c9982c1e19936c34a83f120bdfc8
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data.tar.gz.sig
CHANGED
Binary file
|
data/lib/parallel.rb
CHANGED
@@ -1,4 +1,3 @@
|
|
1
|
-
require 'thread' # to get Thread.exclusive
|
2
1
|
require 'rbconfig'
|
3
2
|
require 'parallel/version'
|
4
3
|
require 'parallel/processor_count'
|
@@ -15,6 +14,8 @@ module Parallel
|
|
15
14
|
class Kill < StandardError
|
16
15
|
end
|
17
16
|
|
17
|
+
Stop = Object.new
|
18
|
+
|
18
19
|
INTERRUPT_SIGNAL = :SIGINT
|
19
20
|
|
20
21
|
class ExceptionWrapper
|
@@ -47,9 +48,9 @@ module Parallel
|
|
47
48
|
# process died
|
48
49
|
end
|
49
50
|
|
50
|
-
def work(
|
51
|
+
def work(data)
|
51
52
|
begin
|
52
|
-
Marshal.dump(
|
53
|
+
Marshal.dump(data, write)
|
53
54
|
rescue Errno::EPIPE
|
54
55
|
raise DeadWorker
|
55
56
|
end
|
@@ -62,6 +63,66 @@ module Parallel
|
|
62
63
|
end
|
63
64
|
end
|
64
65
|
|
66
|
+
class ItemWrapper
|
67
|
+
def initialize(array, mutex)
|
68
|
+
@lambda = (array.respond_to?(:call) && array) || queue_wrapper(array)
|
69
|
+
@items = array.to_a unless @lambda # turn Range and other Enumerable-s into an Array
|
70
|
+
@mutex = mutex
|
71
|
+
@index = -1
|
72
|
+
end
|
73
|
+
|
74
|
+
def producer?
|
75
|
+
@lambda
|
76
|
+
end
|
77
|
+
|
78
|
+
def each_with_index(&block)
|
79
|
+
if producer?
|
80
|
+
loop do
|
81
|
+
item, index = self.next
|
82
|
+
break unless index
|
83
|
+
yield(item, index)
|
84
|
+
end
|
85
|
+
else
|
86
|
+
@items.each_with_index(&block)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def next
|
91
|
+
if producer?
|
92
|
+
# - index and item stay in sync
|
93
|
+
# - do not call lambda after it has returned Stop
|
94
|
+
item, index = @mutex.synchronize do
|
95
|
+
return if @stopped
|
96
|
+
item = @lambda.call
|
97
|
+
@stopped = (item == Parallel::Stop)
|
98
|
+
return if @stopped
|
99
|
+
[item, @index += 1]
|
100
|
+
end
|
101
|
+
else
|
102
|
+
index = @mutex.synchronize { @index += 1 }
|
103
|
+
return if index >= size
|
104
|
+
item = @items[index]
|
105
|
+
end
|
106
|
+
[item, index]
|
107
|
+
end
|
108
|
+
|
109
|
+
def size
|
110
|
+
@items.size
|
111
|
+
end
|
112
|
+
|
113
|
+
def pack(item, index)
|
114
|
+
producer? ? [item, index] : index
|
115
|
+
end
|
116
|
+
|
117
|
+
def unpack(data)
|
118
|
+
producer? ? data : [@items[data], data]
|
119
|
+
end
|
120
|
+
|
121
|
+
def queue_wrapper(array)
|
122
|
+
array.is_a?(::Queue) && lambda { array.pop(false) }
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
65
126
|
class << self
|
66
127
|
def in_threads(options={:count => 2})
|
67
128
|
count, options = extract_count_from_options(options)
|
@@ -96,8 +157,7 @@ module Parallel
|
|
96
157
|
end
|
97
158
|
|
98
159
|
def map(array, options = {}, &block)
|
99
|
-
|
100
|
-
options[:mutex] ||= Mutex.new
|
160
|
+
options[:mutex] = Mutex.new
|
101
161
|
|
102
162
|
if RUBY_PLATFORM =~ /java/ and not options[:in_processes]
|
103
163
|
method = :in_threads
|
@@ -114,26 +174,36 @@ module Parallel
|
|
114
174
|
size = 0
|
115
175
|
end
|
116
176
|
end
|
117
|
-
|
177
|
+
|
178
|
+
items = ItemWrapper.new(array, options[:mutex])
|
179
|
+
|
180
|
+
size = [items.producer? ? size : items.size, size].min
|
118
181
|
|
119
182
|
options[:return_results] = (options[:preserve_results] != false || !!options[:finish])
|
120
|
-
add_progress_bar!(
|
183
|
+
add_progress_bar!(items, options)
|
121
184
|
|
122
185
|
if size == 0
|
123
|
-
work_direct(
|
186
|
+
work_direct(items, options, &block)
|
124
187
|
elsif method == :in_threads
|
125
|
-
work_in_threads(
|
188
|
+
work_in_threads(items, options.merge(:count => size), &block)
|
126
189
|
else
|
127
|
-
work_in_processes(
|
190
|
+
work_in_processes(items, options.merge(:count => size), &block)
|
128
191
|
end
|
129
192
|
end
|
130
193
|
|
131
|
-
def
|
194
|
+
def map_with_index(array, options={}, &block)
|
195
|
+
map(array, options.merge(:with_index => true), &block)
|
196
|
+
end
|
197
|
+
|
198
|
+
private
|
199
|
+
|
200
|
+
def add_progress_bar!(items, options)
|
132
201
|
if title = options[:progress]
|
202
|
+
raise "Progressbar and producers don't mix" if items.producer?
|
133
203
|
require 'ruby-progressbar'
|
134
204
|
progress = ProgressBar.create(
|
135
205
|
:title => title,
|
136
|
-
:total =>
|
206
|
+
:total => items.size,
|
137
207
|
:format => '%t |%E | %B | %a'
|
138
208
|
)
|
139
209
|
old_finish = options[:finish]
|
@@ -144,15 +214,10 @@ module Parallel
|
|
144
214
|
end
|
145
215
|
end
|
146
216
|
|
147
|
-
def map_with_index(array, options={}, &block)
|
148
|
-
map(array, options.merge(:with_index => true), &block)
|
149
|
-
end
|
150
|
-
|
151
|
-
private
|
152
217
|
|
153
|
-
def work_direct(
|
218
|
+
def work_direct(items, options)
|
154
219
|
results = []
|
155
|
-
|
220
|
+
items.each_with_index do |e,i|
|
156
221
|
results << (options[:with_index] ? yield(e,i) : yield(e))
|
157
222
|
end
|
158
223
|
results
|
@@ -160,20 +225,18 @@ module Parallel
|
|
160
225
|
|
161
226
|
def work_in_threads(items, options, &block)
|
162
227
|
results = []
|
163
|
-
current = -1
|
164
228
|
exception = nil
|
165
229
|
|
166
230
|
in_threads(options[:count]) do
|
167
231
|
# as long as there are more items, work on one of them
|
168
232
|
loop do
|
169
233
|
break if exception
|
170
|
-
|
171
|
-
|
172
|
-
break if index >= items.size
|
234
|
+
item, index = items.next
|
235
|
+
break unless index
|
173
236
|
|
174
237
|
begin
|
175
|
-
results[index] = with_instrumentation
|
176
|
-
call_with_index(
|
238
|
+
results[index] = with_instrumentation item, index, options do
|
239
|
+
call_with_index(item, index, options, &block)
|
177
240
|
end
|
178
241
|
rescue StandardError => e
|
179
242
|
exception = e
|
@@ -187,9 +250,9 @@ module Parallel
|
|
187
250
|
|
188
251
|
def work_in_processes(items, options, &blk)
|
189
252
|
workers = create_workers(items, options, &blk)
|
190
|
-
current_index = -1
|
191
253
|
results = []
|
192
254
|
exception = nil
|
255
|
+
|
193
256
|
kill_on_ctrl_c(workers.map(&:pid)) do
|
194
257
|
in_threads(options[:count]) do |i|
|
195
258
|
worker = workers[i]
|
@@ -198,11 +261,11 @@ module Parallel
|
|
198
261
|
begin
|
199
262
|
loop do
|
200
263
|
break if exception
|
201
|
-
index =
|
202
|
-
break
|
264
|
+
item, index = items.next
|
265
|
+
break unless index
|
203
266
|
|
204
|
-
output = with_instrumentation
|
205
|
-
worker.work(index)
|
267
|
+
output = with_instrumentation item, index, options do
|
268
|
+
worker.work(items.pack(item, index))
|
206
269
|
end
|
207
270
|
|
208
271
|
if ExceptionWrapper === output
|
@@ -264,9 +327,10 @@ module Parallel
|
|
264
327
|
|
265
328
|
def process_incoming_jobs(read, write, items, options, &block)
|
266
329
|
while !read.eof?
|
267
|
-
|
330
|
+
data = Marshal.load(read)
|
331
|
+
item, index = items.unpack(data)
|
268
332
|
result = begin
|
269
|
-
call_with_index(
|
333
|
+
call_with_index(item, index, options, &block)
|
270
334
|
rescue StandardError => e
|
271
335
|
ExceptionWrapper.new(e)
|
272
336
|
end
|
@@ -355,8 +419,8 @@ module Parallel
|
|
355
419
|
end
|
356
420
|
end
|
357
421
|
|
358
|
-
def call_with_index(
|
359
|
-
args = [
|
422
|
+
def call_with_index(item, index, options, &block)
|
423
|
+
args = [item]
|
360
424
|
args << index if options[:with_index]
|
361
425
|
if options[:return_results]
|
362
426
|
block.call(*args)
|
data/lib/parallel/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: parallel
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Michael Grosser
|
@@ -30,7 +30,7 @@ cert_chain:
|
|
30
30
|
F5etKHZg0j3eHO31/i2HnswY04lqGImUu6aM5EnijFTB7PPW2KwKKM4+kKDYFdlw
|
31
31
|
/0WV1Ng2/Y6qsHwmqGg2VlYj2h4=
|
32
32
|
-----END CERTIFICATE-----
|
33
|
-
date: 2014-08-
|
33
|
+
date: 2014-08-30 00:00:00.000000000 Z
|
34
34
|
dependencies: []
|
35
35
|
description:
|
36
36
|
email: michael@grosser.it
|
metadata.gz.sig
CHANGED
Binary file
|