class Zold::ThreadPool

Thread pool

Public Class Methods

new(title, log: Log::NULL) click to toggle source
# File lib/zold/thread_pool.rb, line 34
def initialize(title, log: Log::NULL)
  @title = title
  @log = log
  @threads = []
  @start = Time.now
end

Public Instance Methods

add() { || ... } click to toggle source

Add a new thread

# File lib/zold/thread_pool.rb, line 42
def add
  raise 'Block must be given to start()' unless block_given?
  latch = Concurrent::CountDownLatch.new(1)
  thread = Thread.start do
    Thread.current.name = @title
    VerboseThread.new(@log).run do
      latch.count_down
      yield
    end
  end
  latch.wait
  Thread.current.thread_variable_set(
    :kids,
    (Thread.current.thread_variable_get(:kids) || []) + [thread]
  )
  @threads << thread
end
count() click to toggle source

How many threads are in there

# File lib/zold/thread_pool.rb, line 97
def count
  @threads.count
end
empty?() click to toggle source

Is it empty and has no threads?

# File lib/zold/thread_pool.rb, line 92
def empty?
  @threads.empty?
end
exists?(name) click to toggle source

A thread with this name exists?

# File lib/zold/thread_pool.rb, line 102
def exists?(name)
  !@threads.find { |t| t.name == name }.nil?
end
join(sec) click to toggle source
# File lib/zold/thread_pool.rb, line 60
def join(sec)
  @threads.each { |t| t.join(sec) }
end
kill() click to toggle source

Kill them all immediately and close the pool

# File lib/zold/thread_pool.rb, line 65
    def kill
      if @threads.empty?
        @log.debug("Thread pool \"#{@title}\" terminated with no threads")
        return
      end
      @log.debug("Stopping \"#{@title}\" thread pool with #{@threads.count} threads: \
#{@threads.map { |t| "#{t.name}/#{t.status}" }.join(', ')}...")
      start = Time.new
      begin
        join(0.1)
      ensure
        @threads.each do |t|
          (t.thread_variable_get(:kids) || []).each(&:kill)
          t.kill
          sleep(0.001) while t.alive? # I believe it's a bug in Ruby, this line fixes it
          Thread.current.thread_variable_set(
            :kids,
            (Thread.current.thread_variable_get(:kids) || []) - [t]
          )
        end
        @log.debug("Thread pool \"#{@title}\" terminated all threads in #{Age.new(start)}, \
it was alive for #{Age.new(@start)}: #{@threads.map { |t| "#{t.name}/#{t.status}" }.join(', ')}")
        @threads.clear
      end
    end
to_json() click to toggle source

As a hash map

# File lib/zold/thread_pool.rb, line 107
def to_json
  @threads.map do |t|
    {
      name: t.name,
      status: t.status,
      alive: t.alive?,
      vars: Hash[t.thread_variables.map { |v| [v.to_s, t.thread_variable_get(v)] }]
    }
  end
end
to_s() click to toggle source

As a text

# File lib/zold/thread_pool.rb, line 119
def to_s
  @threads.map do |t|
    [
      "#{t.name}: status=#{t.status}; alive=#{t.alive?}",
      'Vars: ' + t.thread_variables.map { |v| "#{v}=\"#{t.thread_variable_get(v)}\"" }.join('; '),
      t.backtrace.nil? ? 'NO BACKTRACE' : "  #{t.backtrace.join("\n  ")}"
    ].join("\n")
  end
end