14

私は奇妙なエラー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 
+0

スレッド内で例外をキャッチしようとすると、同じエラーが発生しますか? –

+0

それを処理する方法は、クエリの性質に応じて少し異なります。私はそれらが別々のスレッドで実行されるので、各スレッドのクエリは文脈上互いに分離されていると仮定します。この場合、私は間違いなくスレッド自体の中でエラーを処理します。タイムアウト時に3回の再試行を行い、「スレッドリターンコード」を設定してスレッドを終了します。あなたがアップデートをしているならば、それらをトランザクションにパックしてください - ActiveRecordはこれをサポートしています。 –

+0

あなたがブロックを終了するまで 'rescue nil'を追加しようとしたことがありますか? – Stone

答えて

0

database.ymlにpool:10を設定する必要があります。あなたが限界に達したようです。

関連する問題