Class: Zold::Hands

Inherits:
Object
  • Object
show all
Defined in:
lib/zold/hands.rb

Overview

Hands

Class Method Summary collapse

Class Method Details

.exec(threads, set = (0..threads - 1).to_a) ⇒ Object

Run this code in many threads



69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
# 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) ⇒ Object

Start



52
53
54
55
56
57
58
59
60
61
# 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

.stopObject

Stop



64
65
66
# File 'lib/zold/hands.rb', line 64

def self.stop
  POOL.kill
end

.thresholdObject



44
45
46
47
48
49
# 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