cartodb-4.29/lib/tasks/thread_pool.rb
2020-06-15 10:58:47 +08:00

57 lines
1.2 KiB
Ruby

require 'monitor'
# Basic thread pool with (unlimited) queue
# Based on http://burgestrand.se/code/ruby-thread-pool/
class ThreadPool
def initialize(size, sleep_time=0.1)
@size = size
@sleep_time = sleep_time
@workers_queue = []
@workers_queue.extend(MonitorMixin)
@mutex = @workers_queue.new_cond
@pool = Array.new(@size) do |i|
Thread.new do
Thread.current[:id] = i
catch(:exit) do
loop do
unless @workers_queue.empty?
@workers_queue.synchronize do
@mutex.wait_while { @workers_queue.empty? }
end
job, args = @workers_queue.pop
job.call(*args)
job = nil
args = nil
end
end
end
end
end
end
def schedule(*args, &block)
enqueued = false
begin
if @workers_queue.length < @size
@workers_queue.synchronize do
@workers_queue << [block, args]
enqueued = true
@mutex.broadcast
end
else
sleep(@sleep_time)
end
end while (!enqueued)
end
def shutdown
@size.times do
schedule { throw :exit }
end
@pool.map(&:join)
end
end