class Zold::Hands

Hands

Constants

POOL

Pool of threads

QUEUE

Queue of jobs

Public Class Methods

exec(threads, set = (0..threads - 1).to_a) { |r, i| ... } click to toggle source

Run this code in many threads

# File lib/zold/hands.rb, line 69
def self.exec(threads, set = (0..threads - 1).to_a)
  raise 'The thread pool is empty' if POOL.empty?
  raise "Number of threads #{threads} has to be positive" unless threads.positive?
  list = set.dup
  total = [threads, set.count].min
  if total == 1
    list.each_with_index { |r, i| yield(r, i) }
  elsif total.positive?
    idx = Concurrent::AtomicFixnum.new
    mutex = Mutex.new
    latch = Concurrent::CountDownLatch.new(total)
    errors = Set.new
    total.times do |i|
      QUEUE.push(
        lambda do
          Thread.current.name = "#{@title}-#{i}"
          loop do
            r = mutex.synchronize { list.pop }
            break if r.nil?
            yield(r, idx.increment - 1)
          end
        rescue StandardError => e
          errors << e
          raise e
        ensure
          latch.count_down
        end
      )
    end
    latch.wait
    raise errors.to_a[0] unless errors.empty?
  end
end
start(max = Hands.threshold, log: Log::NULL) click to toggle source

Start

# File lib/zold/hands.rb, line 52
def self.start(max = Hands.threshold, log: Log::NULL)
  while POOL.count < max
    POOL.add do
      Endless.new('hands').run do
        QUEUE.pop.call
      end
    end
  end
  log.debug("There are #{POOL.count} threads in the 'hands' pool")
end
stop() click to toggle source

Stop

# File lib/zold/hands.rb, line 64
def self.stop
  POOL.kill
end
threshold() click to toggle source
# File lib/zold/hands.rb, line 44
def self.threshold
  advised = Total::Mem.new.bytes / (128 * 1024 * 1024)
  [Concurrent.processor_count * 4, [advised, 4].max].min
rescue Total::CantDetect
  4
end