私は奇妙なエラーundefined method `run_callbacks' for nil:NilClass
を追跡し、このサンプルコードで再現できました。接続プールでアクティブなレコードのタイムアウトを処理する適切な方法は何ですか?
基本的に問題は、アクティブなレコードがタイムアウト(デフォルトは5秒)を取得していますが、未定義のメソッド例外がスローされていることです。
しかし、とにかく、これを処理する正しい方法は何ですか?私の実際のコードでは、実際の作業を行うのに忙しいスレッドがたくさんありますが、時にはこのエラーが発生することがあります。したがって、puts
が実際のコードであると想像してください。私はこの問題が発生したときに既存のスレッドが動作し続けることを望みます。
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
このコードをそのまま実行すると例外が発生します。私が4秒に睡眠を減らすなら、私はしません。ここでは、6秒の睡眠の出力があります。
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
スレッド内で例外をキャッチしようとすると、同じエラーが発生しますか? –
それを処理する方法は、クエリの性質に応じて少し異なります。私はそれらが別々のスレッドで実行されるので、各スレッドのクエリは文脈上互いに分離されていると仮定します。この場合、私は間違いなくスレッド自体の中でエラーを処理します。タイムアウト時に3回の再試行を行い、「スレッドリターンコード」を設定してスレッドを終了します。あなたがアップデートをしているならば、それらをトランザクションにパックしてください - ActiveRecordはこれをサポートしています。 –
あなたがブロックを終了するまで 'rescue nil'を追加しようとしたことがありますか? – Stone