14

He rastreado un extraño error undefined method `run_callbacks' for nil:NilClass y he podido reproducirlo con este código de muestra.¿Cuál es la forma correcta de manejar los tiempos de espera para el registro activo con un grupo de conexiones?

Básicamente el problema es que el registro activo está obteniendo un tiempo de espera (el valor predeterminado es 5s) pero arrojando una excepción de método indefinido, lo cual me parece incorrecto.

Pero, de todos modos, ¿cuál es la forma correcta de manejar esto? En mi código real, tengo un montón de hilos que están ocupados haciendo un trabajo real, pero de vez en cuando respondo a este error. Entonces imagine que el puts es el código real. Quiero que los hilos existentes sigan funcionando cuando esto suceda.

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 

Si ejecuto este código como soy, obtengo la excepción. Si reduzco el sueño a 4s no lo hago. Aquí está la salida con el sueño 6s.

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

¿Obtiene el mismo error si intenta capturar la excepción dentro del hilo? –

+0

Cómo manejarlo depende un poco de la naturaleza de sus consultas. Supongo que, dado que se ejecutan en hilos separados, las consultas en cada hilo están contextualmente aisladas entre sí. En este caso, definitivamente manejaría el error dentro del hilo mismo. Haga 3 intentos en tiempos de espera y luego configure un "código de retorno de hilo" y salga del hilo. Si está haciendo actualizaciones, por supuesto, empaquételas en una transacción. ActiveRecord es compatible con esto. –

+0

Si solo quieres codificar para seguir funcionando, ¿has intentado agregar 'rescue nil' al final de tu bloque? – Stone

Respuesta

0

Debe establecer el grupo: 10 en su base de datos.yml. Parece que has llegado al límite.

Cuestiones relacionadas