parallel 1.27.0 → 2.0.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a657608c1d396b6c563f8905778d64d24c4ae6bb010e716e60a45ccc4a71295e
4
- data.tar.gz: eb26d89f92521fed38f1bdf99f6374a2cca2e3f4c1557a7f3f92ed81d396ffb7
3
+ metadata.gz: 0556b829a420b259f2c4610988421e0b21516101042373b14cb9acfe870e9c8d
4
+ data.tar.gz: 6c0a7aa158fb4a905902c1ef94e3901b75c73518754faa57a421cea4e82df6c7
5
5
  SHA512:
6
- metadata.gz: d7accf7f9b3d74e1e76f7b89db8f9040d23876e8373a6d6fa9b31e927b9ca4ce8b13330ffd888871795c79d6e3bbe7b17aa787789146ffed67f46c21fa9af3ad
7
- data.tar.gz: ead77e379ad1c18641ca8d0457214af393beeee60fe4e5558c69d601f6f269628ce2830b6a35a7fe66e461b88fbebad33dd9bb8b767324030294e2a8f7164d8d
6
+ metadata.gz: 76173acf1c6a08e53bf12cfe4c039b02ca5d891b7a0bfed7024a2ba0093d7cbe42790f6e2ac1ee8e195c99e3582c24fb2abb27c8882541361bdc794492df86f3
7
+ data.tar.gz: a032ace70ba955047cd3d1bb73c85af8bf67664f41e2d61ccdc0d1298277754a8ce190e1f33d654507236a1208d532e7fe973cfe5abee55abd46f7b13b70be36
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  module Parallel
3
- VERSION = Version = '1.27.0' # rubocop:disable Naming/ConstantName
3
+ VERSION = Version = '2.0.1' # rubocop:disable Naming/ConstantName
4
4
  end
data/lib/parallel.rb CHANGED
@@ -15,6 +15,17 @@ module Parallel
15
15
  super()
16
16
  @value = value
17
17
  end
18
+
19
+ # marshal_dump that is used for ruby exceptions
20
+ # avoid dumping the cause since nobody needs that and it can include undumpable exceptions
21
+ def _dump(_depth)
22
+ Marshal.dump(@value)
23
+ end
24
+
25
+ # marshal_load that is used for ruby exceptions
26
+ def self._load(data)
27
+ new(Marshal.load(data))
28
+ end
18
29
  end
19
30
 
20
31
  class Kill < Break
@@ -255,7 +266,7 @@ module Parallel
255
266
 
256
267
  if options[:in_processes] && options[:in_threads]
257
268
  raise ArgumentError, "Please specify only one of `in_processes` or `in_threads`."
258
- elsif RUBY_PLATFORM =~ (/java/) && !options[:in_processes]
269
+ elsif RUBY_PLATFORM =~ /java/ && !options[:in_processes]
259
270
  method = :in_threads
260
271
  size = options[method] || processor_count
261
272
  elsif options[:in_threads]
@@ -460,62 +471,86 @@ module Parallel
460
471
  raise ArgumentError, "pass the code you want to execute as `ractor: [ClassName, :method_name]`"
461
472
  end
462
473
 
474
+ use_port = defined?(Ractor::Port)
475
+
463
476
  # build
464
- ractors = Array.new(options.fetch(:count)) do
465
- Ractor.new do
466
- loop do
467
- got = receive
468
- (klass, method_name), item, index = got
469
- break if index == :break
470
- begin
471
- Ractor.yield [nil, klass.send(method_name, item), item, index]
472
- rescue StandardError => e
473
- Ractor.yield [e, nil, item, index]
474
- end
475
- end
476
- 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
477
481
  end
478
482
 
479
483
  # start
480
- ractors.dup.each do |ractor|
481
- if (set = job_factory.next)
482
- item, index = set
484
+ ports.dup.each do |port, ractor|
485
+ if (job = job_factory.next)
486
+ item, index = job
483
487
  instrument_start item, index, options
484
488
  ractor.send [callback, item, index]
485
- else
486
- ractor.send([[nil, nil], nil, :break]) # stop the ractor
487
- ractors.delete ractor
489
+ else # not enough work, `receive` would hang
490
+ ractor_stop ractor
491
+ ports.delete port
488
492
  end
489
493
  end
490
494
 
491
- # replace with new items
492
- while (set = job_factory.next)
493
- item_next, index_next = set
494
- 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]
495
500
  if exception
496
- ractors.delete done
501
+ ports.delete done_port
497
502
  break
498
503
  end
499
- instrument_finish item, index, result, options
500
- results_mutex.synchronize { results[index] = (options[:preserve_results] == false ? nil : result) }
504
+ ractor_result item_prev, index_prev, result, results, results_mutex, options
501
505
 
506
+ # send new
507
+ item_next, index_next = job
502
508
  instrument_start item_next, index_next, options
503
- done.send([callback, item_next, index_next])
509
+ done_ractor.send([callback, item_next, index_next])
504
510
  end
505
511
 
506
512
  # finish
507
- ractors.each do |ractor|
508
- (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
509
515
  exception ||= new_exception
510
516
  next if new_exception
511
- instrument_finish item, index, result, options
512
- results_mutex.synchronize { results[index] = (options[:preserve_results] == false ? nil : result) }
513
- ractor.send([[nil, nil], nil, :break]) # stop the ractor
517
+ ractor_result item, index, result, results, results_mutex, options
518
+ ractor_stop ractor
514
519
  end
515
520
 
516
521
  exception || results
517
522
  end
518
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
+
519
554
  def work_in_processes(job_factory, options, &blk)
520
555
  workers = create_workers(job_factory, options, &blk)
521
556
  results = []
@@ -621,7 +656,7 @@ module Parallel
621
656
  # https://github.com/rspec/rspec-support/blob/673133cdd13b17077b3d88ece8d7380821f8d7dc/lib/rspec/support.rb#L132-L140
622
657
  rescue NoMemoryError, SignalException, Interrupt, SystemExit # rubocop:disable Lint/ShadowedException
623
658
  raise $!
624
- rescue Exception # # rubocop:disable Lint/RescueException
659
+ rescue Exception # rubocop:disable Lint/RescueException
625
660
  ExceptionWrapper.new($!)
626
661
  end
627
662
 
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: parallel
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.27.0
4
+ version: 2.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Michael Grosser
8
8
  bindir: bin
9
9
  cert_chain: []
10
- date: 2025-04-14 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
11
  dependencies: []
12
12
  email: michael@grosser.it
13
13
  executables: []
@@ -22,9 +22,11 @@ licenses:
22
22
  - MIT
23
23
  metadata:
24
24
  bug_tracker_uri: https://github.com/grosser/parallel/issues
25
- documentation_uri: https://github.com/grosser/parallel/blob/v1.27.0/Readme.md
26
- source_code_uri: https://github.com/grosser/parallel/tree/v1.27.0
25
+ documentation_uri: https://github.com/grosser/parallel/blob/v2.0.1/Readme.md
26
+ source_code_uri: https://github.com/grosser/parallel/tree/v2.0.1
27
27
  wiki_uri: https://github.com/grosser/parallel/wiki
28
+ changelog_uri: https://github.com/grosser/parallel/blob/v2.0.1/CHANGELOG.md
29
+ rubygems_mfa_required: 'true'
28
30
  rdoc_options: []
29
31
  require_paths:
30
32
  - lib
@@ -32,14 +34,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
32
34
  requirements:
33
35
  - - ">="
34
36
  - !ruby/object:Gem::Version
35
- version: '2.7'
37
+ version: '3.3'
36
38
  required_rubygems_version: !ruby/object:Gem::Requirement
37
39
  requirements:
38
40
  - - ">="
39
41
  - !ruby/object:Gem::Version
40
42
  version: '0'
41
43
  requirements: []
42
- rubygems_version: 3.6.2
44
+ rubygems_version: 4.0.3
43
45
  specification_version: 4
44
46
  summary: Run any kind of code in parallel processes
45
47
  test_files: []