14

Wyszukałem dziwny błąd undefined method `run_callbacks' for nil:NilClass i udało się go odtworzyć za pomocą tego przykładowego kodu.jaki jest właściwy sposób na obsługę limitów czasu dla aktywnego rekordu z pulą połączeń?

Zasadniczo problem polega na tym, że aktywnym rekordem jest przekroczenie limitu czasu (domyślnie 5s), ale wyrzucenie nieokreślonego wyjątku metody, co wydaje mi się błędne.

Ale w każdym razie, jaki jest właściwy sposób, aby sobie z tym poradzić? W moim prawdziwym kodzie, mam kilka wątków, które są zajęte wykonywaniem prawdziwej pracy, ale czasami trafiam ten błąd. Wyobraź sobie, że kod puts jest prawdziwy. Chcę, aby istniejące wątki dalej działały, kiedy to się stanie.

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 

Jeśli uruchomię ten kod, otrzymuję wyjątek. Jeśli zmniejszę sen do 4s, nie. Oto wynik ze snu 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

Czy otrzymujesz ten sam błąd, jeśli próbujesz uchwycić wyjątek wewnątrz wątku? –

+0

Sposób obsługi zależy od charakteru zapytań. Zakładam, że ponieważ są one uruchamiane w oddzielnych wątkach, zapytania w każdym wątku są izolowane od siebie w kontekście. W tym przypadku zdecydowanie zniosę błąd w samym wątku. Wykonaj 3 ponowienia na timeoutach, a następnie ustaw "kod powrotu wątku" i wyjdź z wątku. Jeśli robisz aktualizacje, oczywiście spakuj je do transakcji - ActiveRecord obsługuje to. –

+0

Jeśli chcesz tylko zachować kod, aby kontynuować, czy próbowałeś dodać "zero do końca" na końcu bloku? – Stone

Odpowiedz

0

Powinieneś ustawić pulę: 10 w pliku database.yml. Wygląda na to, że osiągnąłeś limit.

Powiązane problemy