parallel 1.21.0 → 1.22.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/parallel/processor_count.rb +2 -3
- data/lib/parallel/version.rb +1 -1
- data/lib/parallel.rb +84 -4
- metadata +5 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7efbfe49c3df93ae88464b4bd4ce85d1aaccc9c173e1a81e7cf9100fe182982c
|
4
|
+
data.tar.gz: 7e82ff83bd44c96da760d83ab665baed41bc62d53f010987951c805cf41723e4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a81cae96dd4dcfa1d287ce3e5893c830de3cb8e305236db4170db81f94de021f187da0d21462b7df5e99310002c14984fbb00aef818936c13d0ae834c1c1b2e7
|
7
|
+
data.tar.gz: 79c099a5f1f8bdad3d9f187829213d242087779605f14fb421f0172c1de1a8f853b4f13045935410a989d845d08e736e9552c8e3b9a6c3763d2dfdd27ede7daf
|
@@ -1,11 +1,10 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
-
require 'etc'
|
3
|
-
|
4
2
|
module Parallel
|
5
3
|
# TODO: inline this method into parallel.rb and kill physical_processor_count in next major release
|
6
4
|
module ProcessorCount
|
7
5
|
# Number of processors seen by the OS, used for process scheduling
|
8
6
|
def processor_count
|
7
|
+
require 'etc'
|
9
8
|
@processor_count ||= Integer(ENV['PARALLEL_PROCESSOR_COUNT'] || Etc.nprocessors)
|
10
9
|
end
|
11
10
|
|
@@ -19,7 +18,7 @@ module Parallel
|
|
19
18
|
when /linux/
|
20
19
|
cores = {} # unique physical ID / core ID combinations
|
21
20
|
phy = 0
|
22
|
-
|
21
|
+
File.read("/proc/cpuinfo").scan(/^physical id.*|^core id.*/) do |ln|
|
23
22
|
if ln.start_with?("physical")
|
24
23
|
phy = ln[/\d+/]
|
25
24
|
elsif ln.start_with?("core")
|
data/lib/parallel/version.rb
CHANGED
data/lib/parallel.rb
CHANGED
@@ -264,6 +264,9 @@ module Parallel
|
|
264
264
|
elsif options[:in_threads]
|
265
265
|
method = :in_threads
|
266
266
|
size = options[method]
|
267
|
+
elsif options[:in_ractors]
|
268
|
+
method = :in_ractors
|
269
|
+
size = options[method]
|
267
270
|
else
|
268
271
|
method = :in_processes
|
269
272
|
if Process.respond_to?(:fork)
|
@@ -285,6 +288,8 @@ module Parallel
|
|
285
288
|
work_direct(job_factory, options, &block)
|
286
289
|
elsif method == :in_threads
|
287
290
|
work_in_threads(job_factory, options.merge(count: size), &block)
|
291
|
+
elsif method == :in_ractors
|
292
|
+
work_in_ractors(job_factory, options.merge(count: size), &block)
|
288
293
|
else
|
289
294
|
work_in_processes(job_factory, options.merge(count: size), &block)
|
290
295
|
end
|
@@ -382,6 +387,72 @@ module Parallel
|
|
382
387
|
exception || results
|
383
388
|
end
|
384
389
|
|
390
|
+
def work_in_ractors(job_factory, options)
|
391
|
+
exception = nil
|
392
|
+
results = []
|
393
|
+
results_mutex = Mutex.new # arrays are not thread-safe on jRuby
|
394
|
+
|
395
|
+
callback = options[:ractor]
|
396
|
+
if block_given? || !callback
|
397
|
+
raise ArgumentError, "pass the code you want to execute as `ractor: [ClassName, :method_name]`"
|
398
|
+
end
|
399
|
+
|
400
|
+
# build
|
401
|
+
ractors = Array.new(options.fetch(:count)) do
|
402
|
+
Ractor.new do
|
403
|
+
loop do
|
404
|
+
got = receive
|
405
|
+
(klass, method_name), item, index = got
|
406
|
+
break if index == :break
|
407
|
+
begin
|
408
|
+
Ractor.yield [nil, klass.send(method_name, item), item, index]
|
409
|
+
rescue StandardError => e
|
410
|
+
Ractor.yield [e, nil, item, index]
|
411
|
+
end
|
412
|
+
end
|
413
|
+
end
|
414
|
+
end
|
415
|
+
|
416
|
+
# start
|
417
|
+
ractors.dup.each do |ractor|
|
418
|
+
if set = job_factory.next
|
419
|
+
item, index = set
|
420
|
+
instrument_start item, index, options
|
421
|
+
ractor.send [callback, item, index]
|
422
|
+
else
|
423
|
+
ractor.send([[nil, nil], nil, :break]) # stop the ractor
|
424
|
+
ractors.delete ractor
|
425
|
+
end
|
426
|
+
end
|
427
|
+
|
428
|
+
# replace with new items
|
429
|
+
while set = job_factory.next
|
430
|
+
item_next, index_next = set
|
431
|
+
done, (exception, result, item, index) = Ractor.select(*ractors)
|
432
|
+
if exception
|
433
|
+
ractors.delete done
|
434
|
+
break
|
435
|
+
end
|
436
|
+
instrument_finish item, index, result, options
|
437
|
+
results_mutex.synchronize { results[index] = (options[:preserve_results] == false ? nil : result) }
|
438
|
+
|
439
|
+
instrument_start item_next, index_next, options
|
440
|
+
done.send([callback, item_next, index_next])
|
441
|
+
end
|
442
|
+
|
443
|
+
# finish
|
444
|
+
ractors.each do |ractor|
|
445
|
+
(new_exception, result, item, index) = ractor.take
|
446
|
+
exception ||= new_exception
|
447
|
+
next if new_exception
|
448
|
+
instrument_finish item, index, result, options
|
449
|
+
results_mutex.synchronize { results[index] = (options[:preserve_results] == false ? nil : result) }
|
450
|
+
ractor.send([[nil, nil], nil, :break]) # stop the ractor
|
451
|
+
end
|
452
|
+
|
453
|
+
exception || results
|
454
|
+
end
|
455
|
+
|
385
456
|
def work_in_processes(job_factory, options, &blk)
|
386
457
|
workers = create_workers(job_factory, options, &blk)
|
387
458
|
results = []
|
@@ -426,6 +497,7 @@ module Parallel
|
|
426
497
|
end
|
427
498
|
end
|
428
499
|
end
|
500
|
+
|
429
501
|
exception || results
|
430
502
|
end
|
431
503
|
|
@@ -521,12 +593,20 @@ module Parallel
|
|
521
593
|
end
|
522
594
|
|
523
595
|
def with_instrumentation(item, index, options)
|
524
|
-
|
525
|
-
on_finish = options[:finish]
|
526
|
-
options[:mutex].synchronize { on_start.call(item, index) } if on_start
|
596
|
+
instrument_start(item, index, options)
|
527
597
|
result = yield
|
528
|
-
|
598
|
+
instrument_finish(item, index, result, options)
|
529
599
|
result unless options[:preserve_results] == false
|
530
600
|
end
|
601
|
+
|
602
|
+
def instrument_finish(item, index, result, options)
|
603
|
+
return unless on_finish = options[:finish]
|
604
|
+
options[:mutex].synchronize { on_finish.call(item, index, result) }
|
605
|
+
end
|
606
|
+
|
607
|
+
def instrument_start(item, index, options)
|
608
|
+
return unless on_start = options[:start]
|
609
|
+
options[:mutex].synchronize { on_start.call(item, index) }
|
610
|
+
end
|
531
611
|
end
|
532
612
|
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.22.1
|
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: 2022-03-25 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description:
|
14
14
|
email: michael@grosser.it
|
@@ -25,8 +25,8 @@ licenses:
|
|
25
25
|
- MIT
|
26
26
|
metadata:
|
27
27
|
bug_tracker_uri: https://github.com/grosser/parallel/issues
|
28
|
-
documentation_uri: https://github.com/grosser/parallel/blob/v1.
|
29
|
-
source_code_uri: https://github.com/grosser/parallel/tree/v1.
|
28
|
+
documentation_uri: https://github.com/grosser/parallel/blob/v1.22.1/Readme.md
|
29
|
+
source_code_uri: https://github.com/grosser/parallel/tree/v1.22.1
|
30
30
|
wiki_uri: https://github.com/grosser/parallel/wiki
|
31
31
|
post_install_message:
|
32
32
|
rdoc_options: []
|
@@ -43,7 +43,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
43
43
|
- !ruby/object:Gem::Version
|
44
44
|
version: '0'
|
45
45
|
requirements: []
|
46
|
-
rubygems_version: 3.
|
46
|
+
rubygems_version: 3.1.6
|
47
47
|
signing_key:
|
48
48
|
specification_version: 4
|
49
49
|
summary: Run any kind of code in parallel processes
|