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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4dd167566b23262ceacbd640fda95c5e8d0d8149cc430f51ada53765a927cb18
4
- data.tar.gz: 6a21c00b1109d5c665a471aec4a7af7d213ded2fc9123132b6576ee65ceb1758
3
+ metadata.gz: 1b517593727e82ec4dd9a897612cfca6ed731f788b84bceee4166a455bbc339d
4
+ data.tar.gz: a47a4fbac65ebe5ecad57c3d2c78df64f261e3770637cacbb2063b91369538bf
5
5
  SHA512:
6
- metadata.gz: 1f8a810c3b7fa77e8dd2b2539238b856b9b4ea40b5df49cf2cc4af2afbd2a73d9b6f34baab614c41e7b3b8bfe1917413bfbd014f647c5b4b96e7243d5433523d
7
- data.tar.gz: 0bef1c7dc19b4738e228985512ee6cce1915f67ee29161b743821f69366d561ed8c3c5cbd4d9e6829342108fe9f10329563770d1978a660a04c58c0d9e2c8461
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
- IO.read("/proc/cpuinfo").scan(/^physical id.*|^core id.*/) do |ln|
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")
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  module Parallel
3
- VERSION = Version = '1.21.0' # rubocop:disable Naming/ConstantName
3
+ VERSION = Version = '1.22.0' # rubocop:disable Naming/ConstantName
4
4
  end
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
- on_start = options[:start]
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
- options[:mutex].synchronize { on_finish.call(item, index, result) } if on_finish
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.21.0
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: 2021-09-13 00:00:00.000000000 Z
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.21.0/Readme.md
29
- source_code_uri: https://github.com/grosser/parallel/tree/v1.21.0
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.2.16
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: []