parallel 1.28.0 → 2.0.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.
Files changed (4) hide show
  1. checksums.yaml +4 -4
  2. data/lib/parallel/version.rb +1 -1
  3. data/lib/parallel.rb +58 -34
  4. metadata +6 -10
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4b172785b4c554ff694b90a15c5314d32dceac1cb7caf8abf313cf8b75621b54
4
- data.tar.gz: efd61bfc5273f2f105e64391294a636c4d2fceaab650fc6e0346f0764f9dcfa6
3
+ metadata.gz: 8b4863387079ee1a7107f51efb9a4dd4abf570dd6913748d25f3587ec0fc1cf8
4
+ data.tar.gz: f84c3fbe014c170a4d7c30f9c24cb8f1c99d667ae54206eaa61bdd59f4526c00
5
5
  SHA512:
6
- metadata.gz: dc0fca1c5760881f31e2c4b229c0bc27d173f070d278f79e6fa9afb3dabae7e6b899fe919409a431506ee45e27a486e2b812250f74ce14ee1e08a62f0a948297
7
- data.tar.gz: 1ef1b735cfa30ee8b3f92e6d9075752742ae72ee704acbe509e218dd9957715d8776b17b96e6cca2b4d56182e27dd913a8f2f65e67c0a30c7bf50c69c566332c
6
+ metadata.gz: c6f71618f6261a184e2472c0fd6482645901d298ff7f299cccb0540b98c1dc334d650e271186a8e6e1e07ee9cc6e29ca0f05d13e1c8a83ed9426ec349534ac33
7
+ data.tar.gz: 7dc0069e5b9dbf798089afc4e81015747fc5f5cd2b01ecbc138eaf0173b107f6c978a13bd96962ffc7d679272f8e3675cae3f129d8d958eb18925f50de9481a6
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  module Parallel
3
- VERSION = Version = '1.28.0' # rubocop:disable Naming/ConstantName
3
+ VERSION = Version = '2.0.0' # rubocop:disable Naming/ConstantName
4
4
  end
data/lib/parallel.rb CHANGED
@@ -266,7 +266,7 @@ module Parallel
266
266
 
267
267
  if options[:in_processes] && options[:in_threads]
268
268
  raise ArgumentError, "Please specify only one of `in_processes` or `in_threads`."
269
- elsif RUBY_PLATFORM =~ (/java/) && !options[:in_processes]
269
+ elsif RUBY_PLATFORM =~ /java/ && !options[:in_processes]
270
270
  method = :in_threads
271
271
  size = options[method] || processor_count
272
272
  elsif options[:in_threads]
@@ -471,62 +471,86 @@ module Parallel
471
471
  raise ArgumentError, "pass the code you want to execute as `ractor: [ClassName, :method_name]`"
472
472
  end
473
473
 
474
+ use_port = defined?(Ractor::Port)
475
+
474
476
  # build
475
- ractors = Array.new(options.fetch(:count)) do
476
- Ractor.new do
477
- loop do
478
- got = receive
479
- (klass, method_name), item, index = got
480
- break if index == :break
481
- begin
482
- Ractor.yield [nil, klass.send(method_name, item), item, index]
483
- rescue StandardError => e
484
- Ractor.yield [e, nil, item, index]
485
- end
486
- end
487
- end
477
+ ports = {} # port (ruby 4+) or ractor (ruby 3) => ractor
478
+ options.fetch(:count).times do
479
+ port, ractor = ractor_build(use_port)
480
+ ports[port] = ractor
488
481
  end
489
482
 
490
483
  # start
491
- ractors.dup.each do |ractor|
492
- if (set = job_factory.next)
493
- item, index = set
484
+ ports.dup.each do |port, ractor|
485
+ if (job = job_factory.next)
486
+ item, index = job
494
487
  instrument_start item, index, options
495
488
  ractor.send [callback, item, index]
496
- else
497
- ractor.send([[nil, nil], nil, :break]) # stop the ractor
498
- ractors.delete ractor
489
+ else # not enough work, `receive` would hang
490
+ ractor_stop ractor
491
+ ports.delete port
499
492
  end
500
493
  end
501
494
 
502
- # replace with new items
503
- while (set = job_factory.next)
504
- item_next, index_next = set
505
- done, (exception, result, item, index) = Ractor.select(*ractors)
495
+ # receive result and send new items to done ractors
496
+ while (job = job_factory.next)
497
+ # receive result
498
+ done_port, (exception, result, item_prev, index_prev) = Ractor.select(*ports.keys)
499
+ done_ractor = ports[done_port]
506
500
  if exception
507
- ractors.delete done
501
+ ports.delete done_port
508
502
  break
509
503
  end
510
- instrument_finish item, index, result, options
511
- results_mutex.synchronize { results[index] = (options[:preserve_results] == false ? nil : result) }
504
+ ractor_result item_prev, index_prev, result, results, results_mutex, options
512
505
 
506
+ # send new
507
+ item_next, index_next = job
513
508
  instrument_start item_next, index_next, options
514
- done.send([callback, item_next, index_next])
509
+ done_ractor.send([callback, item_next, index_next])
515
510
  end
516
511
 
517
512
  # finish
518
- ractors.each do |ractor|
519
- (new_exception, result, item, index) = ractor.take
513
+ ports.each do |port, ractor|
514
+ (new_exception, result, item, index) = use_port ? port.receive : ractor.take
520
515
  exception ||= new_exception
521
516
  next if new_exception
522
- instrument_finish item, index, result, options
523
- results_mutex.synchronize { results[index] = (options[:preserve_results] == false ? nil : result) }
524
- ractor.send([[nil, nil], nil, :break]) # stop the ractor
517
+ ractor_result item, index, result, results, results_mutex, options
518
+ ractor_stop ractor
525
519
  end
526
520
 
527
521
  exception || results
528
522
  end
529
523
 
524
+ def ractor_build(use_port)
525
+ args = use_port ? [Ractor::Port.new] : []
526
+ ractor = Ractor.new(*args) do |port|
527
+ loop do
528
+ (klass, method_name), item, index = receive
529
+ break if index == :break
530
+ begin
531
+ result = [nil, klass.send(method_name, item), item, index]
532
+ rescue StandardError => e
533
+ result = [e, nil, item, index]
534
+ end
535
+ if port
536
+ port.send result
537
+ else
538
+ Ractor.yield result
539
+ end
540
+ end
541
+ end
542
+ [use_port ? args.first : ractor, ractor]
543
+ end
544
+
545
+ def ractor_result(item, index, result, results, results_mutex, options)
546
+ instrument_finish item, index, result, options
547
+ results_mutex.synchronize { results[index] = (options[:preserve_results] == false ? nil : result) }
548
+ end
549
+
550
+ def ractor_stop(ractor)
551
+ ractor.send([[nil, nil], nil, :break])
552
+ end
553
+
530
554
  def work_in_processes(job_factory, options, &blk)
531
555
  workers = create_workers(job_factory, options, &blk)
532
556
  results = []
@@ -632,7 +656,7 @@ module Parallel
632
656
  # https://github.com/rspec/rspec-support/blob/673133cdd13b17077b3d88ece8d7380821f8d7dc/lib/rspec/support.rb#L132-L140
633
657
  rescue NoMemoryError, SignalException, Interrupt, SystemExit # rubocop:disable Lint/ShadowedException
634
658
  raise $!
635
- rescue Exception # # rubocop:disable Lint/RescueException
659
+ rescue Exception # rubocop:disable Lint/RescueException
636
660
  ExceptionWrapper.new($!)
637
661
  end
638
662
 
metadata CHANGED
@@ -1,16 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: parallel
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.28.0
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Michael Grosser
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2026-04-02 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies: []
13
- description:
14
12
  email: michael@grosser.it
15
13
  executables: []
16
14
  extensions: []
@@ -24,10 +22,9 @@ licenses:
24
22
  - MIT
25
23
  metadata:
26
24
  bug_tracker_uri: https://github.com/grosser/parallel/issues
27
- documentation_uri: https://github.com/grosser/parallel/blob/v1.28.0/Readme.md
28
- source_code_uri: https://github.com/grosser/parallel/tree/v1.28.0
25
+ documentation_uri: https://github.com/grosser/parallel/blob/v2.0.0/Readme.md
26
+ source_code_uri: https://github.com/grosser/parallel/tree/v2.0.0
29
27
  wiki_uri: https://github.com/grosser/parallel/wiki
30
- post_install_message:
31
28
  rdoc_options: []
32
29
  require_paths:
33
30
  - lib
@@ -35,15 +32,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
35
32
  requirements:
36
33
  - - ">="
37
34
  - !ruby/object:Gem::Version
38
- version: '2.7'
35
+ version: '3.3'
39
36
  required_rubygems_version: !ruby/object:Gem::Requirement
40
37
  requirements:
41
38
  - - ">="
42
39
  - !ruby/object:Gem::Version
43
40
  version: '0'
44
41
  requirements: []
45
- rubygems_version: 3.4.10
46
- signing_key:
42
+ rubygems_version: 4.0.3
47
43
  specification_version: 4
48
44
  summary: Run any kind of code in parallel processes
49
45
  test_files: []