2013-03-12 7 views
5

In unserer Rails App. Wir speichern ein Modell (Video). Wir haben einen Rückruf für das Objekt:Warum kann mein Resque-Job das Objekt nicht finden?

after_create :send_to_background_job, :if => :persisted? 

Das Verfahren sieht so aus:

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

Wenn der Arbeiter aufgerufen wird. Es macht folgendes:

class AddVideo 
    @queue = :high 

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

Resque-web meldet einen Fehler:

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

Welche ein bisschen seltsam ist, weil, wenn ich Konsole gehen auf Schienen für dieses Video zu sehen. Das gibt es. Darüber hinaus läuft der Aufruf Resque.enqueue(AddVideo, 51061) ein zweites Mal, ohne Fehler.

Es ist, als ob es mehr Zeit braucht, um den Datensatz in der Datenbank zu speichern, als zum Erstellen des Arbeiters/Jobs. Aber auch diese Aussage addiert sich nicht, da das Objekt den Resque-Job erst aufruft, nachdem das Objekt gespeichert wurde. In Rails erfolgt dies über eine Callback-Methode im Modell (after_create).

Weiß nicht, ob dies eine Rolle in dem Problem spielt. In einer Initialisierer-Datei habe ich:

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 

Antwort

9

Dies geschieht wahrscheinlich, weil die eigentliche Transaktion, in der das Objekt gespeichert wird, ist noch nicht verpflichtet und der Hintergrundjob bereits damit begonnen, daran zu arbeiten.

Sie sollten schalten Sie die after_create zu

after_commit :send_to_background_job, on: :create