ruby 42 lines · 7 steps

A thread pool for thumbnail jobs in Ruby

A fixed set of worker threads pull image jobs off a bounded queue and generate thumbnails concurrently.

Explained by highlit
1class ThumbnailPool
2 def initialize(worker_count: 4, capacity: 100)
3 @queue = SizedQueue.new(capacity)
4 @running = true
5 @workers = Array.new(worker_count) { spawn_worker }
6 end
7 
8 def enqueue(image_id, sizes:)
9 raise "pool shut down" unless @running
10 @queue.push(image_id: image_id, sizes: sizes)
11 end
12 
13 def shutdown
14 @running = false
15 @workers.size.times { @queue.push(:stop) }
16 @workers.each(&:join)
17 end
18 
19 private
20 
21 def spawn_worker
22 Thread.new do
23 loop do
24 job = @queue.pop
25 break if job == :stop
26 
27 process(job)
28 end
29 end
30 end
31 
32 def process(job)
33 image = Image.find(job[:image_id])
34 job[:sizes].each do |size|
35 image.generate_thumbnail(size)
36 end
37 rescue ActiveRecord::RecordNotFound
38 Rails.logger.warn("skipping missing image #{job[:image_id]}")
39 rescue => e
40 Rails.logger.error("thumbnail failed for #{job[:image_id]}: #{e.message}")
41 end
42end
01 / 01
STEP 01

Walkthrough

Space play step click any line
Three takeaways
  1. 1A bounded SizedQueue applies backpressure so producers block instead of overwhelming memory.
  2. 2Poison-pill sentinels like :stop let each worker exit cleanly without killing threads mid-job.
  3. 3Isolating error handling inside the worker loop keeps one bad job from taking down the whole pool.

Related explainers

Share this explainer

Here's the card — post it anywhere.

A thread pool for thumbnail jobs in Ruby — share card
Made with highlit — turn any snippet into a walkthrough like this in about a minute.
Explain your code