concurrent-ruby icon indicating copy to clipboard operation
concurrent-ruby copied to clipboard

CachedThreadPool does not spin down idle threads

Open SamSaffron opened this issue 10 months ago • 13 comments

In the Ruby implementation:

require 'concurrent'

puts "Thread Count: #{Thread.list.count}"

pool = Concurrent::CachedThreadPool.new( min_threads: 0, max_threads: 5, idletime: 1 )

puts "Thread Count: #{Thread.list.count}"
# we have 1 thread for now

5.times do
  pool.post do
    puts "Hello from thread #{Thread.current.object_id}"
  end
end
# we now have 5

sleep 2
puts "Thread Count: #{Thread.list.count}"
# we still have 5

pool.post do
  puts "Hello from thread #{Thread.current.object_id}"
end

sleep 1

puts "Thread Count: #{Thread.list.count}"
# we just issued a prune as a side effect so we have 2

pool.prune_pool
sleep 2
# we need to sleep cause prune_pool is async

puts "Thread Count: #{Thread.list.count}"
# we now have 1 thread

CachedThreadPool only spins down threads when you queue work, so if you are done queuing work you need to remember to wait for it to be done and then issue a #prune_pool call

This is technically very tricky cause you need to carry an extra thread for that. The Ruby design should change so threads just wait idle_time for new work and spin down if no new work arrives.

SamSaffron avatar Dec 19 '24 03:12 SamSaffron