2013-03-12 20 views
5

W naszej aplikacji Rails. Zapisujemy model (wideo). Mamy zwrotnego na tym obiekcie:Dlaczego moje zadanie resque znalezienia obiektu?

after_create :send_to_background_job, :if => :persisted? 

Metoda wygląda następująco:

def send_to_background_job 
    Resque.enqueue(AddVideo, self.id) 
end 

Gdy pracownik jest tzw. Robi, co następuje:

class AddVideo 
    @queue = :high 

    def self.perform(video_id) 
    video = Video.find(video_id) 
    video.original_file_name 
    .... 

Resque-web zgłasza błąd:

AddVideo 
Arguments 
51061 
Exception 
NoMethodError 
Error 
undefined method `original_filename' for nil:NilClass 

co jest trochę dziwne, ponieważ, jeśli pójdę do konsoli Rails spojrzeć do tego filmu. To istnieje. Ponadto wywołanie Resque.enqueue(AddVideo, 51061) po czasie SECOND trwa bez żadnych błędów.

To tak, jakby zapisanie rekordu w bazie danych zajęło więcej czasu, niż utworzenie pracownika/zadania. Ale nawet ta instrukcja nie sumuje się, ponieważ obiekt wywołuje zadanie Resque dopiero po zapisaniu obiektu. W Railsach odbywa się to za pomocą metody wywołania zwrotnego w modelu (after_create).

Nie wiem, czy to odgrywa rolę w tym problemie. W pliku inicjatora, mam:

Resque.before_fork do 
    defined?(ActiveRecord::Base) and 
    ActiveRecord::Base.connection.disconnect! 
end 

Resque.after_fork do 
    defined?(ActiveRecord::Base) and 
    ActiveRecord::Base.establish_connection 
end 

Odpowiedz

9

Prawdopodobnie dzieje się tak dlatego rzeczywista transakcja, w której obiekt jest zapisywany jeszcze nie popełnił, a zadanie tło już rozpoczął pracę na nim.

Należy przełączyć after_create do

after_commit :send_to_background_job, on: :create