What is the appropriate way to handle active logging times with a connection pool?

advertisements

I've tracked down a strange error undefined method `run_callbacks' for nil:NilClass and been able to reproduce it with this sample code.

Basically the problem is active record is getting a timeout (the default is 5s) but throwing an undefined method exception, which seems wrong to me.

But anyway, what's the right way to handle this? In my real code, I have a bunch of threads that are busy doing real work but occasionally I hit this error. So imagine the puts is the real code. I want the existing threads to keep working away when this happens.

threads = []
10.times do |n|

 threads <<  Thread.new {
    ActiveRecord::Base.connection_pool.with_connection do |conn|
      puts "#{n} #{conn}"
      res =  conn.execute("select sleep(6)", :async => true)
    end
  }
end

# block and wait for all threads to finish
threads.each { |t| puts "joined" ; t.join }
rescue Exception => e
  puts  $!, [email protected]
end

If I run this code as is I get the exception. If I reduce the sleep to 4s I don't. Here's the output with the 6s sleep.

joined
0 #<ActiveRecord::ConnectionAdapters::Mysql2Adapter:0xb73c6380>
1 #<ActiveRecord::ConnectionAdapters::Mysql2Adapter:0xb73c5548>
2 #<ActiveRecord::ConnectionAdapters::Mysql2Adapter:0xb73c4fe4>
3 #<ActiveRecord::ConnectionAdapters::Mysql2Adapter:0xb73c4a80>
4 #<ActiveRecord::ConnectionAdapters::Mysql2Adapter:0xb73c451c>
joined
joined
joined
joined
joined
undefined method `run_callbacks' for nil:NilClass
/usr/lib/ruby/gems/1.8/gems/activerecord-2.2.2/lib/active_record/connection_adapters/abstract/connection_pool.rb:212:in `checkin'
sqltst.rb:31:in `join'
sqltst.rb:31
sqltst.rb:31:in `each'
sqltst.rb:31


A lot of work was done in this area for ActiveRecord since this question was posted. Here are some good explanations: http://bibwild.wordpress.com/2012/03/15/activerecord-concurrency-currently-good-news-and-bad/