parallel 1.17.0 → 1.21.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.
- checksums.yaml +4 -4
 - data/lib/parallel/processor_count.rb +27 -26
 - data/lib/parallel/version.rb +2 -1
 - data/lib/parallel.rb +76 -64
 - metadata +9 -6
 
    
        checksums.yaml
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            ---
         
     | 
| 
       2 
2 
     | 
    
         
             
            SHA256:
         
     | 
| 
       3 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       4 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 3 
     | 
    
         
            +
              metadata.gz: 4dd167566b23262ceacbd640fda95c5e8d0d8149cc430f51ada53765a927cb18
         
     | 
| 
      
 4 
     | 
    
         
            +
              data.tar.gz: 6a21c00b1109d5c665a471aec4a7af7d213ded2fc9123132b6576ee65ceb1758
         
     | 
| 
       5 
5 
     | 
    
         
             
            SHA512:
         
     | 
| 
       6 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       7 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 6 
     | 
    
         
            +
              metadata.gz: 1f8a810c3b7fa77e8dd2b2539238b856b9b4ea40b5df49cf2cc4af2afbd2a73d9b6f34baab614c41e7b3b8bfe1917413bfbd014f647c5b4b96e7243d5433523d
         
     | 
| 
      
 7 
     | 
    
         
            +
              data.tar.gz: 0bef1c7dc19b4738e228985512ee6cce1915f67ee29161b743821f69366d561ed8c3c5cbd4d9e6829342108fe9f10329563770d1978a660a04c58c0d9e2c8461
         
     | 
| 
         @@ -1,41 +1,42 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
       1 
2 
     | 
    
         
             
            require 'etc'
         
     | 
| 
       2 
3 
     | 
    
         | 
| 
       3 
4 
     | 
    
         
             
            module Parallel
         
     | 
| 
      
 5 
     | 
    
         
            +
              # TODO: inline this method into parallel.rb and kill physical_processor_count in next major release
         
     | 
| 
       4 
6 
     | 
    
         
             
              module ProcessorCount
         
     | 
| 
       5 
     | 
    
         
            -
                # Number of processors seen by the OS  
     | 
| 
      
 7 
     | 
    
         
            +
                # Number of processors seen by the OS, used for process scheduling
         
     | 
| 
       6 
8 
     | 
    
         
             
                def processor_count
         
     | 
| 
       7 
     | 
    
         
            -
                  @processor_count ||=  
     | 
| 
       8 
     | 
    
         
            -
                    Etc.nprocessors
         
     | 
| 
       9 
     | 
    
         
            -
                  end
         
     | 
| 
      
 9 
     | 
    
         
            +
                  @processor_count ||= Integer(ENV['PARALLEL_PROCESSOR_COUNT'] || Etc.nprocessors)
         
     | 
| 
       10 
10 
     | 
    
         
             
                end
         
     | 
| 
       11 
11 
     | 
    
         | 
| 
       12 
12 
     | 
    
         
             
                # Number of physical processor cores on the current system.
         
     | 
| 
       13 
     | 
    
         
            -
                #
         
     | 
| 
       14 
13 
     | 
    
         
             
                def physical_processor_count
         
     | 
| 
       15 
14 
     | 
    
         
             
                  @physical_processor_count ||= begin
         
     | 
| 
       16 
     | 
    
         
            -
                    ppc = 
     | 
| 
       17 
     | 
    
         
            -
             
     | 
| 
       18 
     | 
    
         
            -
                       
     | 
| 
       19 
     | 
    
         
            -
             
     | 
| 
       20 
     | 
    
         
            -
                       
     | 
| 
       21 
     | 
    
         
            -
             
     | 
| 
       22 
     | 
    
         
            -
             
     | 
| 
       23 
     | 
    
         
            -
                         
     | 
| 
       24 
     | 
    
         
            -
                           
     | 
| 
       25 
     | 
    
         
            -
             
     | 
| 
       26 
     | 
    
         
            -
                           
     | 
| 
       27 
     | 
    
         
            -
             
     | 
| 
      
 15 
     | 
    
         
            +
                    ppc =
         
     | 
| 
      
 16 
     | 
    
         
            +
                      case RbConfig::CONFIG["target_os"]
         
     | 
| 
      
 17 
     | 
    
         
            +
                      when /darwin[12]/
         
     | 
| 
      
 18 
     | 
    
         
            +
                        IO.popen("/usr/sbin/sysctl -n hw.physicalcpu").read.to_i
         
     | 
| 
      
 19 
     | 
    
         
            +
                      when /linux/
         
     | 
| 
      
 20 
     | 
    
         
            +
                        cores = {} # unique physical ID / core ID combinations
         
     | 
| 
      
 21 
     | 
    
         
            +
                        phy = 0
         
     | 
| 
      
 22 
     | 
    
         
            +
                        IO.read("/proc/cpuinfo").scan(/^physical id.*|^core id.*/) do |ln|
         
     | 
| 
      
 23 
     | 
    
         
            +
                          if ln.start_with?("physical")
         
     | 
| 
      
 24 
     | 
    
         
            +
                            phy = ln[/\d+/]
         
     | 
| 
      
 25 
     | 
    
         
            +
                          elsif ln.start_with?("core")
         
     | 
| 
      
 26 
     | 
    
         
            +
                            cid = "#{phy}:#{ln[/\d+/]}"
         
     | 
| 
      
 27 
     | 
    
         
            +
                            cores[cid] = true unless cores[cid]
         
     | 
| 
      
 28 
     | 
    
         
            +
                          end
         
     | 
| 
       28 
29 
     | 
    
         
             
                        end
         
     | 
| 
      
 30 
     | 
    
         
            +
                        cores.count
         
     | 
| 
      
 31 
     | 
    
         
            +
                      when /mswin|mingw/
         
     | 
| 
      
 32 
     | 
    
         
            +
                        require 'win32ole'
         
     | 
| 
      
 33 
     | 
    
         
            +
                        result_set = WIN32OLE.connect("winmgmts://").ExecQuery(
         
     | 
| 
      
 34 
     | 
    
         
            +
                          "select NumberOfCores from Win32_Processor"
         
     | 
| 
      
 35 
     | 
    
         
            +
                        )
         
     | 
| 
      
 36 
     | 
    
         
            +
                        result_set.to_enum.collect(&:NumberOfCores).reduce(:+)
         
     | 
| 
      
 37 
     | 
    
         
            +
                      else
         
     | 
| 
      
 38 
     | 
    
         
            +
                        processor_count
         
     | 
| 
       29 
39 
     | 
    
         
             
                      end
         
     | 
| 
       30 
     | 
    
         
            -
                      cores.count
         
     | 
| 
       31 
     | 
    
         
            -
                    when /mswin|mingw/
         
     | 
| 
       32 
     | 
    
         
            -
                      require 'win32ole'
         
     | 
| 
       33 
     | 
    
         
            -
                      result_set = WIN32OLE.connect("winmgmts://").ExecQuery(
         
     | 
| 
       34 
     | 
    
         
            -
                        "select NumberOfCores from Win32_Processor")
         
     | 
| 
       35 
     | 
    
         
            -
                      result_set.to_enum.collect(&:NumberOfCores).reduce(:+)
         
     | 
| 
       36 
     | 
    
         
            -
                    else
         
     | 
| 
       37 
     | 
    
         
            -
                      processor_count
         
     | 
| 
       38 
     | 
    
         
            -
                    end
         
     | 
| 
       39 
40 
     | 
    
         
             
                    # fall back to logical count if physical info is invalid
         
     | 
| 
       40 
41 
     | 
    
         
             
                    ppc > 0 ? ppc : processor_count
         
     | 
| 
       41 
42 
     | 
    
         
             
                  end
         
     | 
    
        data/lib/parallel/version.rb
    CHANGED
    
    
    
        data/lib/parallel.rb
    CHANGED
    
    | 
         @@ -1,31 +1,40 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
       1 
2 
     | 
    
         
             
            require 'rbconfig'
         
     | 
| 
       2 
3 
     | 
    
         
             
            require 'parallel/version'
         
     | 
| 
       3 
4 
     | 
    
         
             
            require 'parallel/processor_count'
         
     | 
| 
       4 
5 
     | 
    
         | 
| 
       5 
6 
     | 
    
         
             
            module Parallel
         
     | 
| 
       6 
     | 
    
         
            -
              extend  
     | 
| 
      
 7 
     | 
    
         
            +
              extend ProcessorCount
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
              Stop = Object.new.freeze
         
     | 
| 
       7 
10 
     | 
    
         | 
| 
       8 
11 
     | 
    
         
             
              class DeadWorker < StandardError
         
     | 
| 
       9 
12 
     | 
    
         
             
              end
         
     | 
| 
       10 
13 
     | 
    
         | 
| 
       11 
14 
     | 
    
         
             
              class Break < StandardError
         
     | 
| 
      
 15 
     | 
    
         
            +
                attr_reader :value
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
                def initialize(value = nil)
         
     | 
| 
      
 18 
     | 
    
         
            +
                  super()
         
     | 
| 
      
 19 
     | 
    
         
            +
                  @value = value
         
     | 
| 
      
 20 
     | 
    
         
            +
                end
         
     | 
| 
       12 
21 
     | 
    
         
             
              end
         
     | 
| 
       13 
22 
     | 
    
         | 
| 
       14 
     | 
    
         
            -
              class Kill <  
     | 
| 
      
 23 
     | 
    
         
            +
              class Kill < Break
         
     | 
| 
       15 
24 
     | 
    
         
             
              end
         
     | 
| 
       16 
25 
     | 
    
         | 
| 
       17 
26 
     | 
    
         
             
              class UndumpableException < StandardError
         
     | 
| 
       18 
27 
     | 
    
         
             
                attr_reader :backtrace
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
       19 
29 
     | 
    
         
             
                def initialize(original)
         
     | 
| 
       20 
30 
     | 
    
         
             
                  super "#{original.class}: #{original.message}"
         
     | 
| 
       21 
31 
     | 
    
         
             
                  @backtrace = original.backtrace
         
     | 
| 
       22 
32 
     | 
    
         
             
                end
         
     | 
| 
       23 
33 
     | 
    
         
             
              end
         
     | 
| 
       24 
34 
     | 
    
         | 
| 
       25 
     | 
    
         
            -
              Stop = Object.new.freeze
         
     | 
| 
       26 
     | 
    
         
            -
             
     | 
| 
       27 
35 
     | 
    
         
             
              class ExceptionWrapper
         
     | 
| 
       28 
36 
     | 
    
         
             
                attr_reader :exception
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
       29 
38 
     | 
    
         
             
                def initialize(exception)
         
     | 
| 
       30 
39 
     | 
    
         
             
                  # Remove the bindings stack added by the better_errors gem,
         
     | 
| 
       31 
40 
     | 
    
         
             
                  # because it cannot be marshalled
         
     | 
| 
         @@ -36,7 +45,7 @@ module Parallel 
     | 
|
| 
       36 
45 
     | 
    
         
             
                  @exception =
         
     | 
| 
       37 
46 
     | 
    
         
             
                    begin
         
     | 
| 
       38 
47 
     | 
    
         
             
                      Marshal.dump(exception) && exception
         
     | 
| 
       39 
     | 
    
         
            -
                    rescue
         
     | 
| 
      
 48 
     | 
    
         
            +
                    rescue StandardError
         
     | 
| 
       40 
49 
     | 
    
         
             
                      UndumpableException.new(exception)
         
     | 
| 
       41 
50 
     | 
    
         
             
                    end
         
     | 
| 
       42 
51 
     | 
    
         
             
                end
         
     | 
| 
         @@ -45,8 +54,11 @@ module Parallel 
     | 
|
| 
       45 
54 
     | 
    
         
             
              class Worker
         
     | 
| 
       46 
55 
     | 
    
         
             
                attr_reader :pid, :read, :write
         
     | 
| 
       47 
56 
     | 
    
         
             
                attr_accessor :thread
         
     | 
| 
      
 57 
     | 
    
         
            +
             
     | 
| 
       48 
58 
     | 
    
         
             
                def initialize(read, write, pid)
         
     | 
| 
       49 
     | 
    
         
            -
                  @read 
     | 
| 
      
 59 
     | 
    
         
            +
                  @read = read
         
     | 
| 
      
 60 
     | 
    
         
            +
                  @write = write
         
     | 
| 
      
 61 
     | 
    
         
            +
                  @pid = pid
         
     | 
| 
       50 
62 
     | 
    
         
             
                end
         
     | 
| 
       51 
63 
     | 
    
         | 
| 
       52 
64 
     | 
    
         
             
                def stop
         
     | 
| 
         @@ -73,7 +85,7 @@ module Parallel 
     | 
|
| 
       73 
85 
     | 
    
         
             
                  rescue EOFError
         
     | 
| 
       74 
86 
     | 
    
         
             
                    raise DeadWorker
         
     | 
| 
       75 
87 
     | 
    
         
             
                  end
         
     | 
| 
       76 
     | 
    
         
            -
                  raise result.exception if ExceptionWrapper 
     | 
| 
      
 88 
     | 
    
         
            +
                  raise result.exception if result.is_a?(ExceptionWrapper)
         
     | 
| 
       77 
89 
     | 
    
         
             
                  result
         
     | 
| 
       78 
90 
     | 
    
         
             
                end
         
     | 
| 
       79 
91 
     | 
    
         | 
| 
         @@ -102,7 +114,7 @@ module Parallel 
     | 
|
| 
       102 
114 
     | 
    
         
             
                    item, index = @mutex.synchronize do
         
     | 
| 
       103 
115 
     | 
    
         
             
                      return if @stopped
         
     | 
| 
       104 
116 
     | 
    
         
             
                      item = @lambda.call
         
     | 
| 
       105 
     | 
    
         
            -
                      @stopped = (item ==  
     | 
| 
      
 117 
     | 
    
         
            +
                      @stopped = (item == Stop)
         
     | 
| 
       106 
118 
     | 
    
         
             
                      return if @stopped
         
     | 
| 
       107 
119 
     | 
    
         
             
                      [item, @index += 1]
         
     | 
| 
       108 
120 
     | 
    
         
             
                    end
         
     | 
| 
         @@ -140,7 +152,7 @@ module Parallel 
     | 
|
| 
       140 
152 
     | 
    
         
             
                end
         
     | 
| 
       141 
153 
     | 
    
         | 
| 
       142 
154 
     | 
    
         
             
                def queue_wrapper(array)
         
     | 
| 
       143 
     | 
    
         
            -
                  array.respond_to?(:num_waiting) && array.respond_to?(:pop) &&  
     | 
| 
      
 155 
     | 
    
         
            +
                  array.respond_to?(:num_waiting) && array.respond_to?(:pop) && -> { array.pop(false) }
         
     | 
| 
       144 
156 
     | 
    
         
             
                end
         
     | 
| 
       145 
157 
     | 
    
         
             
              end
         
     | 
| 
       146 
158 
     | 
    
         | 
| 
         @@ -156,7 +168,7 @@ module Parallel 
     | 
|
| 
       156 
168 
     | 
    
         | 
| 
       157 
169 
     | 
    
         
             
                    if @to_be_killed.empty?
         
     | 
| 
       158 
170 
     | 
    
         
             
                      old_interrupt = trap_interrupt(signal) do
         
     | 
| 
       159 
     | 
    
         
            -
                         
     | 
| 
      
 171 
     | 
    
         
            +
                        warn 'Parallel execution interrupted, exiting ...'
         
     | 
| 
       160 
172 
     | 
    
         
             
                        @to_be_killed.flatten.each { |pid| kill(pid) }
         
     | 
| 
       161 
173 
     | 
    
         
             
                      end
         
     | 
| 
       162 
174 
     | 
    
         
             
                    end
         
     | 
| 
         @@ -200,45 +212,44 @@ module Parallel 
     | 
|
| 
       200 
212 
     | 
    
         
             
              end
         
     | 
| 
       201 
213 
     | 
    
         | 
| 
       202 
214 
     | 
    
         
             
              class << self
         
     | 
| 
       203 
     | 
    
         
            -
                def in_threads(options={: 
     | 
| 
      
 215 
     | 
    
         
            +
                def in_threads(options = { count: 2 })
         
     | 
| 
      
 216 
     | 
    
         
            +
                  threads = []
         
     | 
| 
      
 217 
     | 
    
         
            +
                  count, = extract_count_from_options(options)
         
     | 
| 
      
 218 
     | 
    
         
            +
             
     | 
| 
       204 
219 
     | 
    
         
             
                  Thread.handle_interrupt(Exception => :never) do
         
     | 
| 
       205 
     | 
    
         
            -
                     
     | 
| 
       206 
     | 
    
         
            -
                      threads = []
         
     | 
| 
       207 
     | 
    
         
            -
                      count, _ = extract_count_from_options(options)
         
     | 
| 
      
 220 
     | 
    
         
            +
                    Thread.handle_interrupt(Exception => :immediate) do
         
     | 
| 
       208 
221 
     | 
    
         
             
                      count.times do |i|
         
     | 
| 
       209 
222 
     | 
    
         
             
                        threads << Thread.new { yield(i) }
         
     | 
| 
       210 
223 
     | 
    
         
             
                      end
         
     | 
| 
       211 
     | 
    
         
            -
                       
     | 
| 
       212 
     | 
    
         
            -
                        threads.map(&:value)
         
     | 
| 
       213 
     | 
    
         
            -
                      end
         
     | 
| 
       214 
     | 
    
         
            -
                    ensure
         
     | 
| 
       215 
     | 
    
         
            -
                      threads.each(&:kill)
         
     | 
| 
      
 224 
     | 
    
         
            +
                      threads.map(&:value)
         
     | 
| 
       216 
225 
     | 
    
         
             
                    end
         
     | 
| 
      
 226 
     | 
    
         
            +
                  ensure
         
     | 
| 
      
 227 
     | 
    
         
            +
                    threads.each(&:kill)
         
     | 
| 
       217 
228 
     | 
    
         
             
                  end
         
     | 
| 
       218 
229 
     | 
    
         
             
                end
         
     | 
| 
       219 
230 
     | 
    
         | 
| 
       220 
231 
     | 
    
         
             
                def in_processes(options = {}, &block)
         
     | 
| 
       221 
232 
     | 
    
         
             
                  count, options = extract_count_from_options(options)
         
     | 
| 
       222 
233 
     | 
    
         
             
                  count ||= processor_count
         
     | 
| 
       223 
     | 
    
         
            -
                  map(0...count, options.merge(: 
     | 
| 
      
 234 
     | 
    
         
            +
                  map(0...count, options.merge(in_processes: count), &block)
         
     | 
| 
       224 
235 
     | 
    
         
             
                end
         
     | 
| 
       225 
236 
     | 
    
         | 
| 
       226 
     | 
    
         
            -
                def each(array, options={}, &block)
         
     | 
| 
       227 
     | 
    
         
            -
                  map(array, options.merge(: 
     | 
| 
      
 237 
     | 
    
         
            +
                def each(array, options = {}, &block)
         
     | 
| 
      
 238 
     | 
    
         
            +
                  map(array, options.merge(preserve_results: false), &block)
         
     | 
| 
       228 
239 
     | 
    
         
             
                end
         
     | 
| 
       229 
240 
     | 
    
         | 
| 
       230 
241 
     | 
    
         
             
                def any?(*args, &block)
         
     | 
| 
       231 
242 
     | 
    
         
             
                  raise "You must provide a block when calling #any?" if block.nil?
         
     | 
| 
       232 
     | 
    
         
            -
                  !each(*args) { |*a| raise  
     | 
| 
      
 243 
     | 
    
         
            +
                  !each(*args) { |*a| raise Kill if block.call(*a) }
         
     | 
| 
       233 
244 
     | 
    
         
             
                end
         
     | 
| 
       234 
245 
     | 
    
         | 
| 
       235 
246 
     | 
    
         
             
                def all?(*args, &block)
         
     | 
| 
       236 
247 
     | 
    
         
             
                  raise "You must provide a block when calling #all?" if block.nil?
         
     | 
| 
       237 
     | 
    
         
            -
                  !!each(*args) { |*a| raise  
     | 
| 
      
 248 
     | 
    
         
            +
                  !!each(*args) { |*a| raise Kill unless block.call(*a) }
         
     | 
| 
       238 
249 
     | 
    
         
             
                end
         
     | 
| 
       239 
250 
     | 
    
         | 
| 
       240 
     | 
    
         
            -
                def each_with_index(array, options={}, &block)
         
     | 
| 
       241 
     | 
    
         
            -
                  each(array, options.merge(: 
     | 
| 
      
 251 
     | 
    
         
            +
                def each_with_index(array, options = {}, &block)
         
     | 
| 
      
 252 
     | 
    
         
            +
                  each(array, options.merge(with_index: true), &block)
         
     | 
| 
       242 
253 
     | 
    
         
             
                end
         
     | 
| 
       243 
254 
     | 
    
         | 
| 
       244 
255 
     | 
    
         
             
                def map(source, options = {}, &block)
         
     | 
| 
         @@ -246,8 +257,8 @@ module Parallel 
     | 
|
| 
       246 
257 
     | 
    
         
             
                  options[:mutex] = Mutex.new
         
     | 
| 
       247 
258 
     | 
    
         | 
| 
       248 
259 
     | 
    
         
             
                  if options[:in_processes] && options[:in_threads]
         
     | 
| 
       249 
     | 
    
         
            -
                    raise ArgumentError 
     | 
| 
       250 
     | 
    
         
            -
                  elsif RUBY_PLATFORM =~ /java/  
     | 
| 
      
 260 
     | 
    
         
            +
                    raise ArgumentError, "Please specify only one of `in_processes` or `in_threads`."
         
     | 
| 
      
 261 
     | 
    
         
            +
                  elsif RUBY_PLATFORM =~ (/java/) && !(options[:in_processes])
         
     | 
| 
       251 
262 
     | 
    
         
             
                    method = :in_threads
         
     | 
| 
       252 
263 
     | 
    
         
             
                    size = options[method] || processor_count
         
     | 
| 
       253 
264 
     | 
    
         
             
                  elsif options[:in_threads]
         
     | 
| 
         @@ -269,20 +280,22 @@ module Parallel 
     | 
|
| 
       269 
280 
     | 
    
         
             
                  options[:return_results] = (options[:preserve_results] != false || !!options[:finish])
         
     | 
| 
       270 
281 
     | 
    
         
             
                  add_progress_bar!(job_factory, options)
         
     | 
| 
       271 
282 
     | 
    
         | 
| 
       272 
     | 
    
         
            -
                   
     | 
| 
       273 
     | 
    
         
            -
                     
     | 
| 
       274 
     | 
    
         
            -
             
     | 
| 
       275 
     | 
    
         
            -
                     
     | 
| 
       276 
     | 
    
         
            -
             
     | 
| 
       277 
     | 
    
         
            -
                     
     | 
| 
       278 
     | 
    
         
            -
             
     | 
| 
       279 
     | 
    
         
            -
             
     | 
| 
       280 
     | 
    
         
            -
             
     | 
| 
       281 
     | 
    
         
            -
                   
     | 
| 
      
 283 
     | 
    
         
            +
                  result =
         
     | 
| 
      
 284 
     | 
    
         
            +
                    if size == 0
         
     | 
| 
      
 285 
     | 
    
         
            +
                      work_direct(job_factory, options, &block)
         
     | 
| 
      
 286 
     | 
    
         
            +
                    elsif method == :in_threads
         
     | 
| 
      
 287 
     | 
    
         
            +
                      work_in_threads(job_factory, options.merge(count: size), &block)
         
     | 
| 
      
 288 
     | 
    
         
            +
                    else
         
     | 
| 
      
 289 
     | 
    
         
            +
                      work_in_processes(job_factory, options.merge(count: size), &block)
         
     | 
| 
      
 290 
     | 
    
         
            +
                    end
         
     | 
| 
      
 291 
     | 
    
         
            +
             
     | 
| 
      
 292 
     | 
    
         
            +
                  return result.value if result.is_a?(Break)
         
     | 
| 
      
 293 
     | 
    
         
            +
                  raise result if result.is_a?(Exception)
         
     | 
| 
      
 294 
     | 
    
         
            +
                  options[:return_results] ? result : source
         
     | 
| 
       282 
295 
     | 
    
         
             
                end
         
     | 
| 
       283 
296 
     | 
    
         | 
| 
       284 
     | 
    
         
            -
                def map_with_index(array, options={}, &block)
         
     | 
| 
       285 
     | 
    
         
            -
                  map(array, options.merge(: 
     | 
| 
      
 297 
     | 
    
         
            +
                def map_with_index(array, options = {}, &block)
         
     | 
| 
      
 298 
     | 
    
         
            +
                  map(array, options.merge(with_index: true), &block)
         
     | 
| 
       286 
299 
     | 
    
         
             
                end
         
     | 
| 
       287 
300 
     | 
    
         | 
| 
       288 
301 
     | 
    
         
             
                def flat_map(*args, &block)
         
     | 
| 
         @@ -336,10 +349,10 @@ module Parallel 
     | 
|
| 
       336 
349 
     | 
    
         
             
                        call_with_index(item, index, options, &block)
         
     | 
| 
       337 
350 
     | 
    
         
             
                      end
         
     | 
| 
       338 
351 
     | 
    
         
             
                    end
         
     | 
| 
       339 
     | 
    
         
            -
                  rescue
         
     | 
| 
      
 352 
     | 
    
         
            +
                  rescue StandardError
         
     | 
| 
       340 
353 
     | 
    
         
             
                    exception = $!
         
     | 
| 
       341 
354 
     | 
    
         
             
                  end
         
     | 
| 
       342 
     | 
    
         
            -
                   
     | 
| 
      
 355 
     | 
    
         
            +
                  exception || results
         
     | 
| 
       343 
356 
     | 
    
         
             
                ensure
         
     | 
| 
       344 
357 
     | 
    
         
             
                  self.worker_number = nil
         
     | 
| 
       345 
358 
     | 
    
         
             
                end
         
     | 
| 
         @@ -360,13 +373,13 @@ module Parallel 
     | 
|
| 
       360 
373 
     | 
    
         
             
                          call_with_index(item, index, options, &block)
         
     | 
| 
       361 
374 
     | 
    
         
             
                        end
         
     | 
| 
       362 
375 
     | 
    
         
             
                        results_mutex.synchronize { results[index] = result }
         
     | 
| 
       363 
     | 
    
         
            -
                      rescue
         
     | 
| 
      
 376 
     | 
    
         
            +
                      rescue StandardError
         
     | 
| 
       364 
377 
     | 
    
         
             
                        exception = $!
         
     | 
| 
       365 
378 
     | 
    
         
             
                      end
         
     | 
| 
       366 
379 
     | 
    
         
             
                    end
         
     | 
| 
       367 
380 
     | 
    
         
             
                  end
         
     | 
| 
       368 
381 
     | 
    
         | 
| 
       369 
     | 
    
         
            -
                   
     | 
| 
      
 382 
     | 
    
         
            +
                  exception || results
         
     | 
| 
       370 
383 
     | 
    
         
             
                end
         
     | 
| 
       371 
384 
     | 
    
         | 
| 
       372 
385 
     | 
    
         
             
                def work_in_processes(job_factory, options, &blk)
         
     | 
| 
         @@ -400,9 +413,9 @@ module Parallel 
     | 
|
| 
       400 
413 
     | 
    
         
             
                            results_mutex.synchronize { results[index] = result } # arrays are not threads safe on jRuby
         
     | 
| 
       401 
414 
     | 
    
         
             
                          rescue StandardError => e
         
     | 
| 
       402 
415 
     | 
    
         
             
                            exception = e
         
     | 
| 
       403 
     | 
    
         
            -
                            if  
     | 
| 
      
 416 
     | 
    
         
            +
                            if exception.is_a?(Kill)
         
     | 
| 
       404 
417 
     | 
    
         
             
                              (workers - [worker]).each do |w|
         
     | 
| 
       405 
     | 
    
         
            -
                                w.thread 
     | 
| 
      
 418 
     | 
    
         
            +
                                w.thread&.kill
         
     | 
| 
       406 
419 
     | 
    
         
             
                                UserInterruptHandler.kill(w.pid)
         
     | 
| 
       407 
420 
     | 
    
         
             
                              end
         
     | 
| 
       408 
421 
     | 
    
         
             
                            end
         
     | 
| 
         @@ -413,19 +426,18 @@ module Parallel 
     | 
|
| 
       413 
426 
     | 
    
         
             
                      end
         
     | 
| 
       414 
427 
     | 
    
         
             
                    end
         
     | 
| 
       415 
428 
     | 
    
         
             
                  end
         
     | 
| 
       416 
     | 
    
         
            -
             
     | 
| 
       417 
     | 
    
         
            -
                  handle_exception(exception, results)
         
     | 
| 
      
 429 
     | 
    
         
            +
                  exception || results
         
     | 
| 
       418 
430 
     | 
    
         
             
                end
         
     | 
| 
       419 
431 
     | 
    
         | 
| 
       420 
     | 
    
         
            -
                def replace_worker(job_factory, workers,  
     | 
| 
      
 432 
     | 
    
         
            +
                def replace_worker(job_factory, workers, index, options, blk)
         
     | 
| 
       421 
433 
     | 
    
         
             
                  options[:mutex].synchronize do
         
     | 
| 
       422 
434 
     | 
    
         
             
                    # old worker is no longer used ... stop it
         
     | 
| 
       423 
     | 
    
         
            -
                    worker = workers[ 
     | 
| 
      
 435 
     | 
    
         
            +
                    worker = workers[index]
         
     | 
| 
       424 
436 
     | 
    
         
             
                    worker.stop
         
     | 
| 
       425 
437 
     | 
    
         | 
| 
       426 
438 
     | 
    
         
             
                    # create a new replacement worker
         
     | 
| 
       427 
439 
     | 
    
         
             
                    running = workers - [worker]
         
     | 
| 
       428 
     | 
    
         
            -
                    workers[ 
     | 
| 
      
 440 
     | 
    
         
            +
                    workers[index] = worker(job_factory, options.merge(started_workers: running, worker_number: index), &blk)
         
     | 
| 
       429 
441 
     | 
    
         
             
                  end
         
     | 
| 
       430 
442 
     | 
    
         
             
                end
         
     | 
| 
       431 
443 
     | 
    
         | 
| 
         @@ -467,11 +479,17 @@ module Parallel 
     | 
|
| 
       467 
479 
     | 
    
         
             
                  until read.eof?
         
     | 
| 
       468 
480 
     | 
    
         
             
                    data = Marshal.load(read)
         
     | 
| 
       469 
481 
     | 
    
         
             
                    item, index = job_factory.unpack(data)
         
     | 
| 
       470 
     | 
    
         
            -
             
     | 
| 
       471 
     | 
    
         
            -
             
     | 
| 
       472 
     | 
    
         
            -
             
     | 
| 
       473 
     | 
    
         
            -
             
     | 
| 
       474 
     | 
    
         
            -
             
     | 
| 
      
 482 
     | 
    
         
            +
             
     | 
| 
      
 483 
     | 
    
         
            +
                    result =
         
     | 
| 
      
 484 
     | 
    
         
            +
                      begin
         
     | 
| 
      
 485 
     | 
    
         
            +
                        call_with_index(item, index, options, &block)
         
     | 
| 
      
 486 
     | 
    
         
            +
                      # https://github.com/rspec/rspec-support/blob/673133cdd13b17077b3d88ece8d7380821f8d7dc/lib/rspec/support.rb#L132-L140
         
     | 
| 
      
 487 
     | 
    
         
            +
                      rescue NoMemoryError, SignalException, Interrupt, SystemExit # rubocop:disable Lint/ShadowedException
         
     | 
| 
      
 488 
     | 
    
         
            +
                        raise $!
         
     | 
| 
      
 489 
     | 
    
         
            +
                      rescue Exception # # rubocop:disable Lint/RescueException
         
     | 
| 
      
 490 
     | 
    
         
            +
                        ExceptionWrapper.new($!)
         
     | 
| 
      
 491 
     | 
    
         
            +
                      end
         
     | 
| 
      
 492 
     | 
    
         
            +
             
     | 
| 
       475 
493 
     | 
    
         
             
                    begin
         
     | 
| 
       476 
494 
     | 
    
         
             
                      Marshal.dump(result, write)
         
     | 
| 
       477 
495 
     | 
    
         
             
                    rescue Errno::EPIPE
         
     | 
| 
         @@ -480,12 +498,6 @@ module Parallel 
     | 
|
| 
       480 
498 
     | 
    
         
             
                  end
         
     | 
| 
       481 
499 
     | 
    
         
             
                end
         
     | 
| 
       482 
500 
     | 
    
         | 
| 
       483 
     | 
    
         
            -
                def handle_exception(exception, results)
         
     | 
| 
       484 
     | 
    
         
            -
                  return nil if [Parallel::Break, Parallel::Kill].include? exception.class
         
     | 
| 
       485 
     | 
    
         
            -
                  raise exception if exception
         
     | 
| 
       486 
     | 
    
         
            -
                  results
         
     | 
| 
       487 
     | 
    
         
            -
                end
         
     | 
| 
       488 
     | 
    
         
            -
             
     | 
| 
       489 
501 
     | 
    
         
             
                # options is either a Integer or a Hash with :count
         
     | 
| 
       490 
502 
     | 
    
         
             
                def extract_count_from_options(options)
         
     | 
| 
       491 
503 
     | 
    
         
             
                  if options.is_a?(Hash)
         
     | 
| 
         @@ -500,10 +512,10 @@ module Parallel 
     | 
|
| 
       500 
512 
     | 
    
         
             
                def call_with_index(item, index, options, &block)
         
     | 
| 
       501 
513 
     | 
    
         
             
                  args = [item]
         
     | 
| 
       502 
514 
     | 
    
         
             
                  args << index if options[:with_index]
         
     | 
| 
      
 515 
     | 
    
         
            +
                  results = block.call(*args)
         
     | 
| 
       503 
516 
     | 
    
         
             
                  if options[:return_results]
         
     | 
| 
       504 
     | 
    
         
            -
                     
     | 
| 
      
 517 
     | 
    
         
            +
                    results
         
     | 
| 
       505 
518 
     | 
    
         
             
                  else
         
     | 
| 
       506 
     | 
    
         
            -
                    block.call(*args)
         
     | 
| 
       507 
519 
     | 
    
         
             
                    nil # avoid GC overhead of passing large results around
         
     | 
| 
       508 
520 
     | 
    
         
             
                  end
         
     | 
| 
       509 
521 
     | 
    
         
             
                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.21.0
         
     | 
| 
       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: 2021-09-13 00:00:00.000000000 Z
         
     | 
| 
       12 
12 
     | 
    
         
             
            dependencies: []
         
     | 
| 
       13 
13 
     | 
    
         
             
            description: 
         
     | 
| 
       14 
14 
     | 
    
         
             
            email: michael@grosser.it
         
     | 
| 
         @@ -23,7 +23,11 @@ files: 
     | 
|
| 
       23 
23 
     | 
    
         
             
            homepage: https://github.com/grosser/parallel
         
     | 
| 
       24 
24 
     | 
    
         
             
            licenses:
         
     | 
| 
       25 
25 
     | 
    
         
             
            - MIT
         
     | 
| 
       26 
     | 
    
         
            -
            metadata: 
     | 
| 
      
 26 
     | 
    
         
            +
            metadata:
         
     | 
| 
      
 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
         
     | 
| 
      
 30 
     | 
    
         
            +
              wiki_uri: https://github.com/grosser/parallel/wiki
         
     | 
| 
       27 
31 
     | 
    
         
             
            post_install_message: 
         
     | 
| 
       28 
32 
     | 
    
         
             
            rdoc_options: []
         
     | 
| 
       29 
33 
     | 
    
         
             
            require_paths:
         
     | 
| 
         @@ -32,15 +36,14 @@ required_ruby_version: !ruby/object:Gem::Requirement 
     | 
|
| 
       32 
36 
     | 
    
         
             
              requirements:
         
     | 
| 
       33 
37 
     | 
    
         
             
              - - ">="
         
     | 
| 
       34 
38 
     | 
    
         
             
                - !ruby/object:Gem::Version
         
     | 
| 
       35 
     | 
    
         
            -
                  version: '2. 
     | 
| 
      
 39 
     | 
    
         
            +
                  version: '2.5'
         
     | 
| 
       36 
40 
     | 
    
         
             
            required_rubygems_version: !ruby/object:Gem::Requirement
         
     | 
| 
       37 
41 
     | 
    
         
             
              requirements:
         
     | 
| 
       38 
42 
     | 
    
         
             
              - - ">="
         
     | 
| 
       39 
43 
     | 
    
         
             
                - !ruby/object:Gem::Version
         
     | 
| 
       40 
44 
     | 
    
         
             
                  version: '0'
         
     | 
| 
       41 
45 
     | 
    
         
             
            requirements: []
         
     | 
| 
       42 
     | 
    
         
            -
             
     | 
| 
       43 
     | 
    
         
            -
            rubygems_version: 2.7.6
         
     | 
| 
      
 46 
     | 
    
         
            +
            rubygems_version: 3.2.16
         
     | 
| 
       44 
47 
     | 
    
         
             
            signing_key: 
         
     | 
| 
       45 
48 
     | 
    
         
             
            specification_version: 4
         
     | 
| 
       46 
49 
     | 
    
         
             
            summary: Run any kind of code in parallel processes
         
     |