6

Rails アプリで。モデルを保存します(ビデオ)。そのオブジェクトにはコールバックがあります。

after_create :send_to_background_job, :if => :persisted?

メソッドは次のようになります。

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

ワーカーが呼び出されたとき。次のことを行います。

class AddVideo
  @queue = :high

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

Resque-web がエラーを報告します:

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

これは少し奇妙です。Rails コンソールにアクセスしてこのビデオを探すとします。それは存在します。さらに、2 回目の呼び出しResque.enqueue(AddVideo, 51061)は、エラーなしで実行されます。

ワーカー/ジョブを作成するよりも、レコードをデータベースに保存する方が時間がかかるようです。しかし、オブジェクトが保存された後にのみオブジェクトが Resque ジョブを呼び出すため、このステートメントでさえ合計されません。Rails では、これはモデルのコールバック メソッドを介して行われます ( after_create)。

これが問題で役割を果たすかどうかはわかりません。初期化ファイルには、次のものがあります。

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
4

1 に答える 1

10

これは、オブジェクトが保存されている実際のトランザクションがまだコミットされておらず、バックグラウンド ジョブが既に処理を開始しているために発生する可能性があります。

after_create をに切り替える必要があります

after_commit :send_to_background_job, on: :create
于 2013-03-12T12:59:38.687 に答える