parallel 1.13.0 → 1.21.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
- data/lib/parallel/processor_count.rb +28 -76
- data/lib/parallel/version.rb +2 -1
- data/lib/parallel.rb +101 -72
- metadata +9 -6
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 4dd167566b23262ceacbd640fda95c5e8d0d8149cc430f51ada53765a927cb18
|
|
4
|
+
data.tar.gz: 6a21c00b1109d5c665a471aec4a7af7d213ded2fc9123132b6576ee65ceb1758
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 1f8a810c3b7fa77e8dd2b2539238b856b9b4ea40b5df49cf2cc4af2afbd2a73d9b6f34baab614c41e7b3b8bfe1917413bfbd014f647c5b4b96e7243d5433523d
|
|
7
|
+
data.tar.gz: 0bef1c7dc19b4738e228985512ee6cce1915f67ee29161b743821f69366d561ed8c3c5cbd4d9e6829342108fe9f10329563770d1978a660a04c58c0d9e2c8461
|
|
@@ -1,90 +1,42 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
end
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
require 'etc'
|
|
4
3
|
|
|
5
4
|
module Parallel
|
|
5
|
+
# TODO: inline this method into parallel.rb and kill physical_processor_count in next major release
|
|
6
6
|
module ProcessorCount
|
|
7
|
-
# Number of processors seen by the OS
|
|
8
|
-
#
|
|
9
|
-
# * AIX: /usr/sbin/pmcycles (AIX 5+), /usr/sbin/lsdev
|
|
10
|
-
# * BSD: /sbin/sysctl
|
|
11
|
-
# * Cygwin: /proc/cpuinfo
|
|
12
|
-
# * Darwin: /usr/bin/hwprefs, /usr/sbin/sysctl
|
|
13
|
-
# * HP-UX: /usr/sbin/ioscan
|
|
14
|
-
# * IRIX: /usr/sbin/sysconf
|
|
15
|
-
# * Linux: /proc/cpuinfo
|
|
16
|
-
# * Minix 3+: /proc/cpuinfo
|
|
17
|
-
# * Solaris: /usr/sbin/psrinfo
|
|
18
|
-
# * Tru64 UNIX: /usr/sbin/psrinfo
|
|
19
|
-
# * UnixWare: /usr/sbin/psrinfo
|
|
20
|
-
#
|
|
7
|
+
# Number of processors seen by the OS, used for process scheduling
|
|
21
8
|
def processor_count
|
|
22
|
-
@processor_count ||=
|
|
23
|
-
if defined?(Etc) && Etc.respond_to?(:nprocessors)
|
|
24
|
-
Etc.nprocessors
|
|
25
|
-
else
|
|
26
|
-
os_name = RbConfig::CONFIG["target_os"]
|
|
27
|
-
if os_name =~ /mingw|mswin/
|
|
28
|
-
require 'win32ole'
|
|
29
|
-
result = WIN32OLE.connect("winmgmts://").ExecQuery(
|
|
30
|
-
"select NumberOfLogicalProcessors from Win32_Processor")
|
|
31
|
-
result.to_enum.collect(&:NumberOfLogicalProcessors).reduce(:+)
|
|
32
|
-
elsif File.readable?("/proc/cpuinfo")
|
|
33
|
-
IO.read("/proc/cpuinfo").scan(/^processor/).size
|
|
34
|
-
elsif File.executable?("/usr/bin/hwprefs")
|
|
35
|
-
IO.popen("/usr/bin/hwprefs thread_count").read.to_i
|
|
36
|
-
elsif File.executable?("/usr/sbin/psrinfo")
|
|
37
|
-
IO.popen("/usr/sbin/psrinfo").read.scan(/^.*on-*line/).size
|
|
38
|
-
elsif File.executable?("/usr/sbin/ioscan")
|
|
39
|
-
IO.popen("/usr/sbin/ioscan -kC processor") do |out|
|
|
40
|
-
out.read.scan(/^.*processor/).size
|
|
41
|
-
end
|
|
42
|
-
elsif File.executable?("/usr/sbin/pmcycles")
|
|
43
|
-
IO.popen("/usr/sbin/pmcycles -m").read.count("\n")
|
|
44
|
-
elsif File.executable?("/usr/sbin/lsdev")
|
|
45
|
-
IO.popen("/usr/sbin/lsdev -Cc processor -S 1").read.count("\n")
|
|
46
|
-
elsif File.executable?("/usr/sbin/sysconf") and os_name =~ /irix/i
|
|
47
|
-
IO.popen("/usr/sbin/sysconf NPROC_ONLN").read.to_i
|
|
48
|
-
elsif File.executable?("/usr/sbin/sysctl")
|
|
49
|
-
IO.popen("/usr/sbin/sysctl -n hw.ncpu").read.to_i
|
|
50
|
-
elsif File.executable?("/sbin/sysctl")
|
|
51
|
-
IO.popen("/sbin/sysctl -n hw.ncpu").read.to_i
|
|
52
|
-
else
|
|
53
|
-
$stderr.puts "Unknown platform: " + RbConfig::CONFIG["target_os"]
|
|
54
|
-
$stderr.puts "Assuming 1 processor."
|
|
55
|
-
1
|
|
56
|
-
end
|
|
57
|
-
end
|
|
58
|
-
end
|
|
9
|
+
@processor_count ||= Integer(ENV['PARALLEL_PROCESSOR_COUNT'] || Etc.nprocessors)
|
|
59
10
|
end
|
|
60
11
|
|
|
61
12
|
# Number of physical processor cores on the current system.
|
|
62
|
-
#
|
|
63
13
|
def physical_processor_count
|
|
64
14
|
@physical_processor_count ||= begin
|
|
65
|
-
ppc =
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
15
|
+
ppc =
|
|
16
|
+
case RbConfig::CONFIG["target_os"]
|
|
17
|
+
when /darwin[12]/
|
|
18
|
+
IO.popen("/usr/sbin/sysctl -n hw.physicalcpu").read.to_i
|
|
19
|
+
when /linux/
|
|
20
|
+
cores = {} # unique physical ID / core ID combinations
|
|
21
|
+
phy = 0
|
|
22
|
+
IO.read("/proc/cpuinfo").scan(/^physical id.*|^core id.*/) do |ln|
|
|
23
|
+
if ln.start_with?("physical")
|
|
24
|
+
phy = ln[/\d+/]
|
|
25
|
+
elsif ln.start_with?("core")
|
|
26
|
+
cid = "#{phy}:#{ln[/\d+/]}"
|
|
27
|
+
cores[cid] = true unless cores[cid]
|
|
28
|
+
end
|
|
77
29
|
end
|
|
30
|
+
cores.count
|
|
31
|
+
when /mswin|mingw/
|
|
32
|
+
require 'win32ole'
|
|
33
|
+
result_set = WIN32OLE.connect("winmgmts://").ExecQuery(
|
|
34
|
+
"select NumberOfCores from Win32_Processor"
|
|
35
|
+
)
|
|
36
|
+
result_set.to_enum.collect(&:NumberOfCores).reduce(:+)
|
|
37
|
+
else
|
|
38
|
+
processor_count
|
|
78
39
|
end
|
|
79
|
-
cores.count
|
|
80
|
-
when /mswin|mingw/
|
|
81
|
-
require 'win32ole'
|
|
82
|
-
result_set = WIN32OLE.connect("winmgmts://").ExecQuery(
|
|
83
|
-
"select NumberOfCores from Win32_Processor")
|
|
84
|
-
result_set.to_enum.collect(&:NumberOfCores).reduce(:+)
|
|
85
|
-
else
|
|
86
|
-
processor_count
|
|
87
|
-
end
|
|
88
40
|
# fall back to logical count if physical info is invalid
|
|
89
41
|
ppc > 0 ? ppc : processor_count
|
|
90
42
|
end
|
data/lib/parallel/version.rb
CHANGED
data/lib/parallel.rb
CHANGED
|
@@ -1,31 +1,40 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
1
2
|
require 'rbconfig'
|
|
2
3
|
require 'parallel/version'
|
|
3
4
|
require 'parallel/processor_count'
|
|
4
5
|
|
|
5
6
|
module Parallel
|
|
6
|
-
extend
|
|
7
|
+
extend ProcessorCount
|
|
8
|
+
|
|
9
|
+
Stop = Object.new.freeze
|
|
7
10
|
|
|
8
11
|
class DeadWorker < StandardError
|
|
9
12
|
end
|
|
10
13
|
|
|
11
14
|
class Break < StandardError
|
|
15
|
+
attr_reader :value
|
|
16
|
+
|
|
17
|
+
def initialize(value = nil)
|
|
18
|
+
super()
|
|
19
|
+
@value = value
|
|
20
|
+
end
|
|
12
21
|
end
|
|
13
22
|
|
|
14
|
-
class Kill <
|
|
23
|
+
class Kill < Break
|
|
15
24
|
end
|
|
16
25
|
|
|
17
26
|
class UndumpableException < StandardError
|
|
18
27
|
attr_reader :backtrace
|
|
28
|
+
|
|
19
29
|
def initialize(original)
|
|
20
30
|
super "#{original.class}: #{original.message}"
|
|
21
31
|
@backtrace = original.backtrace
|
|
22
32
|
end
|
|
23
33
|
end
|
|
24
34
|
|
|
25
|
-
Stop = Object.new
|
|
26
|
-
|
|
27
35
|
class ExceptionWrapper
|
|
28
36
|
attr_reader :exception
|
|
37
|
+
|
|
29
38
|
def initialize(exception)
|
|
30
39
|
# Remove the bindings stack added by the better_errors gem,
|
|
31
40
|
# because it cannot be marshalled
|
|
@@ -36,7 +45,7 @@ module Parallel
|
|
|
36
45
|
@exception =
|
|
37
46
|
begin
|
|
38
47
|
Marshal.dump(exception) && exception
|
|
39
|
-
rescue
|
|
48
|
+
rescue StandardError
|
|
40
49
|
UndumpableException.new(exception)
|
|
41
50
|
end
|
|
42
51
|
end
|
|
@@ -45,8 +54,11 @@ module Parallel
|
|
|
45
54
|
class Worker
|
|
46
55
|
attr_reader :pid, :read, :write
|
|
47
56
|
attr_accessor :thread
|
|
57
|
+
|
|
48
58
|
def initialize(read, write, pid)
|
|
49
|
-
@read
|
|
59
|
+
@read = read
|
|
60
|
+
@write = write
|
|
61
|
+
@pid = pid
|
|
50
62
|
end
|
|
51
63
|
|
|
52
64
|
def stop
|
|
@@ -73,7 +85,7 @@ module Parallel
|
|
|
73
85
|
rescue EOFError
|
|
74
86
|
raise DeadWorker
|
|
75
87
|
end
|
|
76
|
-
raise result.exception if ExceptionWrapper
|
|
88
|
+
raise result.exception if result.is_a?(ExceptionWrapper)
|
|
77
89
|
result
|
|
78
90
|
end
|
|
79
91
|
|
|
@@ -102,7 +114,7 @@ module Parallel
|
|
|
102
114
|
item, index = @mutex.synchronize do
|
|
103
115
|
return if @stopped
|
|
104
116
|
item = @lambda.call
|
|
105
|
-
@stopped = (item ==
|
|
117
|
+
@stopped = (item == Stop)
|
|
106
118
|
return if @stopped
|
|
107
119
|
[item, @index += 1]
|
|
108
120
|
end
|
|
@@ -140,7 +152,7 @@ module Parallel
|
|
|
140
152
|
end
|
|
141
153
|
|
|
142
154
|
def queue_wrapper(array)
|
|
143
|
-
array.respond_to?(:num_waiting) && array.respond_to?(:pop) &&
|
|
155
|
+
array.respond_to?(:num_waiting) && array.respond_to?(:pop) && -> { array.pop(false) }
|
|
144
156
|
end
|
|
145
157
|
end
|
|
146
158
|
|
|
@@ -156,7 +168,7 @@ module Parallel
|
|
|
156
168
|
|
|
157
169
|
if @to_be_killed.empty?
|
|
158
170
|
old_interrupt = trap_interrupt(signal) do
|
|
159
|
-
|
|
171
|
+
warn 'Parallel execution interrupted, exiting ...'
|
|
160
172
|
@to_be_killed.flatten.each { |pid| kill(pid) }
|
|
161
173
|
end
|
|
162
174
|
end
|
|
@@ -200,35 +212,44 @@ module Parallel
|
|
|
200
212
|
end
|
|
201
213
|
|
|
202
214
|
class << self
|
|
203
|
-
def in_threads(options={:
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
215
|
+
def in_threads(options = { count: 2 })
|
|
216
|
+
threads = []
|
|
217
|
+
count, = extract_count_from_options(options)
|
|
218
|
+
|
|
219
|
+
Thread.handle_interrupt(Exception => :never) do
|
|
220
|
+
Thread.handle_interrupt(Exception => :immediate) do
|
|
221
|
+
count.times do |i|
|
|
222
|
+
threads << Thread.new { yield(i) }
|
|
223
|
+
end
|
|
224
|
+
threads.map(&:value)
|
|
225
|
+
end
|
|
226
|
+
ensure
|
|
227
|
+
threads.each(&:kill)
|
|
228
|
+
end
|
|
208
229
|
end
|
|
209
230
|
|
|
210
231
|
def in_processes(options = {}, &block)
|
|
211
232
|
count, options = extract_count_from_options(options)
|
|
212
233
|
count ||= processor_count
|
|
213
|
-
map(0...count, options.merge(:
|
|
234
|
+
map(0...count, options.merge(in_processes: count), &block)
|
|
214
235
|
end
|
|
215
236
|
|
|
216
|
-
def each(array, options={}, &block)
|
|
217
|
-
map(array, options.merge(:
|
|
237
|
+
def each(array, options = {}, &block)
|
|
238
|
+
map(array, options.merge(preserve_results: false), &block)
|
|
218
239
|
end
|
|
219
240
|
|
|
220
241
|
def any?(*args, &block)
|
|
221
242
|
raise "You must provide a block when calling #any?" if block.nil?
|
|
222
|
-
!each(*args) { |*a| raise
|
|
243
|
+
!each(*args) { |*a| raise Kill if block.call(*a) }
|
|
223
244
|
end
|
|
224
245
|
|
|
225
246
|
def all?(*args, &block)
|
|
226
247
|
raise "You must provide a block when calling #all?" if block.nil?
|
|
227
|
-
!!each(*args) { |*a| raise
|
|
248
|
+
!!each(*args) { |*a| raise Kill unless block.call(*a) }
|
|
228
249
|
end
|
|
229
250
|
|
|
230
|
-
def each_with_index(array, options={}, &block)
|
|
231
|
-
each(array, options.merge(:
|
|
251
|
+
def each_with_index(array, options = {}, &block)
|
|
252
|
+
each(array, options.merge(with_index: true), &block)
|
|
232
253
|
end
|
|
233
254
|
|
|
234
255
|
def map(source, options = {}, &block)
|
|
@@ -236,8 +257,8 @@ module Parallel
|
|
|
236
257
|
options[:mutex] = Mutex.new
|
|
237
258
|
|
|
238
259
|
if options[:in_processes] && options[:in_threads]
|
|
239
|
-
raise ArgumentError
|
|
240
|
-
elsif RUBY_PLATFORM =~ /java/
|
|
260
|
+
raise ArgumentError, "Please specify only one of `in_processes` or `in_threads`."
|
|
261
|
+
elsif RUBY_PLATFORM =~ (/java/) && !(options[:in_processes])
|
|
241
262
|
method = :in_threads
|
|
242
263
|
size = options[method] || processor_count
|
|
243
264
|
elsif options[:in_threads]
|
|
@@ -259,26 +280,33 @@ module Parallel
|
|
|
259
280
|
options[:return_results] = (options[:preserve_results] != false || !!options[:finish])
|
|
260
281
|
add_progress_bar!(job_factory, options)
|
|
261
282
|
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
283
|
+
result =
|
|
284
|
+
if size == 0
|
|
285
|
+
work_direct(job_factory, options, &block)
|
|
286
|
+
elsif method == :in_threads
|
|
287
|
+
work_in_threads(job_factory, options.merge(count: size), &block)
|
|
288
|
+
else
|
|
289
|
+
work_in_processes(job_factory, options.merge(count: size), &block)
|
|
290
|
+
end
|
|
291
|
+
|
|
292
|
+
return result.value if result.is_a?(Break)
|
|
293
|
+
raise result if result.is_a?(Exception)
|
|
294
|
+
options[:return_results] ? result : source
|
|
295
|
+
end
|
|
296
|
+
|
|
297
|
+
def map_with_index(array, options = {}, &block)
|
|
298
|
+
map(array, options.merge(with_index: true), &block)
|
|
272
299
|
end
|
|
273
300
|
|
|
274
|
-
def
|
|
275
|
-
map(
|
|
301
|
+
def flat_map(*args, &block)
|
|
302
|
+
map(*args, &block).flatten(1)
|
|
276
303
|
end
|
|
277
304
|
|
|
278
305
|
def worker_number
|
|
279
306
|
Thread.current[:parallel_worker_number]
|
|
280
307
|
end
|
|
281
308
|
|
|
309
|
+
# TODO: this does not work when doing threads in forks, so should remove and yield the number instead if needed
|
|
282
310
|
def worker_number=(worker_num)
|
|
283
311
|
Thread.current[:parallel_worker_number] = worker_num
|
|
284
312
|
end
|
|
@@ -321,10 +349,10 @@ module Parallel
|
|
|
321
349
|
call_with_index(item, index, options, &block)
|
|
322
350
|
end
|
|
323
351
|
end
|
|
324
|
-
rescue
|
|
352
|
+
rescue StandardError
|
|
325
353
|
exception = $!
|
|
326
354
|
end
|
|
327
|
-
|
|
355
|
+
exception || results
|
|
328
356
|
ensure
|
|
329
357
|
self.worker_number = nil
|
|
330
358
|
end
|
|
@@ -345,21 +373,17 @@ module Parallel
|
|
|
345
373
|
call_with_index(item, index, options, &block)
|
|
346
374
|
end
|
|
347
375
|
results_mutex.synchronize { results[index] = result }
|
|
348
|
-
rescue
|
|
376
|
+
rescue StandardError
|
|
349
377
|
exception = $!
|
|
350
378
|
end
|
|
351
379
|
end
|
|
352
380
|
end
|
|
353
381
|
|
|
354
|
-
|
|
382
|
+
exception || results
|
|
355
383
|
end
|
|
356
384
|
|
|
357
385
|
def work_in_processes(job_factory, options, &blk)
|
|
358
|
-
workers =
|
|
359
|
-
[] # we create workers per job and not beforehand
|
|
360
|
-
else
|
|
361
|
-
create_workers(job_factory, options, &blk)
|
|
362
|
-
end
|
|
386
|
+
workers = create_workers(job_factory, options, &blk)
|
|
363
387
|
results = []
|
|
364
388
|
results_mutex = Mutex.new # arrays are not thread-safe
|
|
365
389
|
exception = nil
|
|
@@ -367,6 +391,8 @@ module Parallel
|
|
|
367
391
|
UserInterruptHandler.kill_on_ctrl_c(workers.map(&:pid), options) do
|
|
368
392
|
in_threads(options) do |i|
|
|
369
393
|
worker = workers[i]
|
|
394
|
+
worker.thread = Thread.current
|
|
395
|
+
worked = false
|
|
370
396
|
|
|
371
397
|
begin
|
|
372
398
|
loop do
|
|
@@ -375,44 +401,43 @@ module Parallel
|
|
|
375
401
|
break unless index
|
|
376
402
|
|
|
377
403
|
if options[:isolation]
|
|
378
|
-
worker = replace_worker(job_factory, workers, i, options, blk)
|
|
404
|
+
worker = replace_worker(job_factory, workers, i, options, blk) if worked
|
|
405
|
+
worked = true
|
|
406
|
+
worker.thread = Thread.current
|
|
379
407
|
end
|
|
380
408
|
|
|
381
|
-
worker.thread = Thread.current
|
|
382
|
-
|
|
383
409
|
begin
|
|
384
410
|
result = with_instrumentation item, index, options do
|
|
385
411
|
worker.work(job_factory.pack(item, index))
|
|
386
412
|
end
|
|
387
413
|
results_mutex.synchronize { results[index] = result } # arrays are not threads safe on jRuby
|
|
388
|
-
rescue
|
|
389
|
-
exception =
|
|
390
|
-
if
|
|
414
|
+
rescue StandardError => e
|
|
415
|
+
exception = e
|
|
416
|
+
if exception.is_a?(Kill)
|
|
391
417
|
(workers - [worker]).each do |w|
|
|
392
|
-
w.thread
|
|
418
|
+
w.thread&.kill
|
|
393
419
|
UserInterruptHandler.kill(w.pid)
|
|
394
420
|
end
|
|
395
421
|
end
|
|
396
422
|
end
|
|
397
423
|
end
|
|
398
424
|
ensure
|
|
399
|
-
worker.stop
|
|
425
|
+
worker.stop
|
|
400
426
|
end
|
|
401
427
|
end
|
|
402
428
|
end
|
|
403
|
-
|
|
404
|
-
handle_exception(exception, results)
|
|
429
|
+
exception || results
|
|
405
430
|
end
|
|
406
431
|
|
|
407
|
-
def replace_worker(job_factory, workers,
|
|
432
|
+
def replace_worker(job_factory, workers, index, options, blk)
|
|
408
433
|
options[:mutex].synchronize do
|
|
409
434
|
# old worker is no longer used ... stop it
|
|
410
|
-
worker = workers[
|
|
411
|
-
worker.stop
|
|
435
|
+
worker = workers[index]
|
|
436
|
+
worker.stop
|
|
412
437
|
|
|
413
438
|
# create a new replacement worker
|
|
414
439
|
running = workers - [worker]
|
|
415
|
-
workers[
|
|
440
|
+
workers[index] = worker(job_factory, options.merge(started_workers: running, worker_number: index), &blk)
|
|
416
441
|
end
|
|
417
442
|
end
|
|
418
443
|
|
|
@@ -454,21 +479,25 @@ module Parallel
|
|
|
454
479
|
until read.eof?
|
|
455
480
|
data = Marshal.load(read)
|
|
456
481
|
item, index = job_factory.unpack(data)
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
482
|
+
|
|
483
|
+
result =
|
|
484
|
+
begin
|
|
485
|
+
call_with_index(item, index, options, &block)
|
|
486
|
+
# https://github.com/rspec/rspec-support/blob/673133cdd13b17077b3d88ece8d7380821f8d7dc/lib/rspec/support.rb#L132-L140
|
|
487
|
+
rescue NoMemoryError, SignalException, Interrupt, SystemExit # rubocop:disable Lint/ShadowedException
|
|
488
|
+
raise $!
|
|
489
|
+
rescue Exception # # rubocop:disable Lint/RescueException
|
|
490
|
+
ExceptionWrapper.new($!)
|
|
491
|
+
end
|
|
492
|
+
|
|
493
|
+
begin
|
|
494
|
+
Marshal.dump(result, write)
|
|
495
|
+
rescue Errno::EPIPE
|
|
496
|
+
return # parent thread already dead
|
|
461
497
|
end
|
|
462
|
-
Marshal.dump(result, write)
|
|
463
498
|
end
|
|
464
499
|
end
|
|
465
500
|
|
|
466
|
-
def handle_exception(exception, results)
|
|
467
|
-
return nil if [Parallel::Break, Parallel::Kill].include? exception.class
|
|
468
|
-
raise exception if exception
|
|
469
|
-
results
|
|
470
|
-
end
|
|
471
|
-
|
|
472
501
|
# options is either a Integer or a Hash with :count
|
|
473
502
|
def extract_count_from_options(options)
|
|
474
503
|
if options.is_a?(Hash)
|
|
@@ -483,10 +512,10 @@ module Parallel
|
|
|
483
512
|
def call_with_index(item, index, options, &block)
|
|
484
513
|
args = [item]
|
|
485
514
|
args << index if options[:with_index]
|
|
515
|
+
results = block.call(*args)
|
|
486
516
|
if options[:return_results]
|
|
487
|
-
|
|
517
|
+
results
|
|
488
518
|
else
|
|
489
|
-
block.call(*args)
|
|
490
519
|
nil # avoid GC overhead of passing large results around
|
|
491
520
|
end
|
|
492
521
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: parallel
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.21.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Michael Grosser
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2021-09-13 00:00:00.000000000 Z
|
|
12
12
|
dependencies: []
|
|
13
13
|
description:
|
|
14
14
|
email: michael@grosser.it
|
|
@@ -23,7 +23,11 @@ files:
|
|
|
23
23
|
homepage: https://github.com/grosser/parallel
|
|
24
24
|
licenses:
|
|
25
25
|
- MIT
|
|
26
|
-
metadata:
|
|
26
|
+
metadata:
|
|
27
|
+
bug_tracker_uri: https://github.com/grosser/parallel/issues
|
|
28
|
+
documentation_uri: https://github.com/grosser/parallel/blob/v1.21.0/Readme.md
|
|
29
|
+
source_code_uri: https://github.com/grosser/parallel/tree/v1.21.0
|
|
30
|
+
wiki_uri: https://github.com/grosser/parallel/wiki
|
|
27
31
|
post_install_message:
|
|
28
32
|
rdoc_options: []
|
|
29
33
|
require_paths:
|
|
@@ -32,15 +36,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
32
36
|
requirements:
|
|
33
37
|
- - ">="
|
|
34
38
|
- !ruby/object:Gem::Version
|
|
35
|
-
version:
|
|
39
|
+
version: '2.5'
|
|
36
40
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
37
41
|
requirements:
|
|
38
42
|
- - ">="
|
|
39
43
|
- !ruby/object:Gem::Version
|
|
40
44
|
version: '0'
|
|
41
45
|
requirements: []
|
|
42
|
-
|
|
43
|
-
rubygems_version: 2.7.6
|
|
46
|
+
rubygems_version: 3.2.16
|
|
44
47
|
signing_key:
|
|
45
48
|
specification_version: 4
|
|
46
49
|
summary: Run any kind of code in parallel processes
|