ActiveRecordを何も考えずに複数スレッドが動作する環境で利用すると、スレッド毎にActiveRecordがコネクションを確保しようとするので、プールサイズを超えてコネクションが確保できないというエラーが発生する。
activerecord-4.1.1/lib/active_record/connection_adapters/abstract/connection_pool.rb:190:in `block in wait_poll': could not obtain a database connection within 5.000 seconds (waited 5.001 seconds) (ActiveRecord::ConnectionTimeoutError)
こちらとしてはコネクションプールがあるのだから、ActiveRecordの方でやりくりをしてよろしくやって欲しいのだが、どうもそういう挙動ではないようだ。
そのようなときには、ActiveRecord::ConnectionAdapters::ConnectionPool#with_connection
メソッドを利用するとよい。具体的には次のように書く。
require 'active_record'
require 'pg'
ActiveRecord::Base.logger = Logger.new(STDERR)
ActiveRecord::Base.establish_connection(adapter: 'postgresql',
host: 'localhost',
database: 'blog',
pool: 1)
class Post < ActiveRecord::Base
end
2.times.map {
Thread.new do
ActiveRecord::Base.connection_pool.with_connection do
Post.take
end
end
}.map(&:join)