I\'m using Rails 5 and Ruby 2.4. How can I figure out, or can you tell by looking at the below, whether there are multiple threads running at the same time?
poo
Your assumption that multiple threads must be running concurrently just because the connection pool is being exhausted is not correct. Just because a connection is still 'checked out' from the connection pool doesn't mean that a query is currently being executed on the checked-out connection in a thread, it simply means that the thread's connection hasn't been checked back in. The thread could be sitting idle but still holding onto a connection from the connection pool as long as it hasn't been explicitly terminated.
Since ActiveRecord Connections are thread-local, you can exhaust the connection pool by running ActiveRecord queries on multiple threads, as you are doing in this case. (Every time Concurrent::FixedThreadPool.new(1)
is called, a new thread is created.) Even if you're only running queries on a single thread at a time, by default a connection will still be held open on every thread until they are terminated.
To avoid this, you can either manually check in connections after using them, or ensure your threads are terminated (killed) so that their connections can be recovered (reaped) by the pool.
To manually check in connections, refer to the ConnectionPool documentation for your options. The easiest way is to wrap your ActiveRecord code in a with_connection
block:
Concurrent::Promise.execute(executor: pool) do
ActiveRecord::Base.connection_pool.with_connection do
# update_attributes, etc
end
end
To ensure all threads are terminated, call #shutdown followed by #wait_for_termination on the thread pool after you're finished using it:
values = promises.map(&:value!)
pool.shutdown
pool.wait_for_termination