parallel 1.21.0 → 1.22.0
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 +1 -1
- data/lib/parallel/version.rb +1 -1
- data/lib/parallel.rb +84 -4
- metadata +9 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1b517593727e82ec4dd9a897612cfca6ed731f788b84bceee4166a455bbc339d
|
4
|
+
data.tar.gz: a47a4fbac65ebe5ecad57c3d2c78df64f261e3770637cacbb2063b91369538bf
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a4e9dbbbf9c0cbff88e12750fd521ee3f65bd1c0de2ab5a18e1a9b7e96c413cd12cce0de985aef9bd4ca0eb8c5e438cf83ac59c88a74e67e38ef73cc7ac8fac9
|
7
|
+
data.tar.gz: 37ddce10ac73b9d722452693914bb889f2d638cbe52fe36ffe37673d6bba9d01601656568408eac29155619df8208892c51861e9033888e549bcaa467ce1f912
|
@@ -19,7 +19,7 @@ module Parallel
|
|
19
19
|
when /linux/
|
20
20
|
cores = {} # unique physical ID / core ID combinations
|
21
21
|
phy = 0
|
22
|
-
|
22
|
+
File.read("/proc/cpuinfo").scan(/^physical id.*|^core id.*/) do |ln|
|
23
23
|
if ln.start_with?("physical")
|
24
24
|
phy = ln[/\d+/]
|
25
25
|
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,16 +1,16 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: parallel
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.22.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Michael Grosser
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-03-21 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
|
-
description:
|
13
|
+
description:
|
14
14
|
email: michael@grosser.it
|
15
15
|
executables: []
|
16
16
|
extensions: []
|
@@ -25,10 +25,10 @@ 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.0/Readme.md
|
29
|
+
source_code_uri: https://github.com/grosser/parallel/tree/v1.22.0
|
30
30
|
wiki_uri: https://github.com/grosser/parallel/wiki
|
31
|
-
post_install_message:
|
31
|
+
post_install_message:
|
32
32
|
rdoc_options: []
|
33
33
|
require_paths:
|
34
34
|
- lib
|
@@ -43,8 +43,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
43
43
|
- !ruby/object:Gem::Version
|
44
44
|
version: '0'
|
45
45
|
requirements: []
|
46
|
-
rubygems_version: 3.
|
47
|
-
signing_key:
|
46
|
+
rubygems_version: 3.3.3
|
47
|
+
signing_key:
|
48
48
|
specification_version: 4
|
49
49
|
summary: Run any kind of code in parallel processes
|
50
50
|
test_files: []
|