Skip to main content

thread_pool_with_sized_queue

🔧 Implement a Bounded Thread Pool with SizedQueue​

To avoid unbounded thread growth under load and to propagate errors gracefully, combine SizedQueue with a fixed worker set. Producers push jobs into the queue, workers pull and execute them, and you can signal shutdown by pushing special sentinel values.

require 'thread'

class ThreadPool
def initialize(size, queue_size)
@jobs = SizedQueue.new(queue_size)
@workers = Array.new(size) do |i|
Thread.new do
loop do
job = @jobs.pop
break if job == :shutdown
begin
job.call
rescue => e
warn "Worker \\##{i} failed: #{e.message}"
end
end
end
end
end

def schedule(&block)
@jobs.push(block)
end

def shutdown
@workers.size.times { @jobs.push(:shutdown) }
@workers.each(&:join)
end
end

# Usage
pool = ThreadPool.new(5, 50)
100.times { |i| pool.schedule { puts "Job #{i}" } }
pool.shutdown

This setup enforces back-pressure (via SizedQueue), catches per-job exceptions, and cleanly joins all threads on shutdown.