Rails RunnerでActive Jobのperform_nowした場合の挙動とかジョブをネストした場合の挙動とか
試した環境:
Active Job v6.0.2.1
DelayedJob v4.1.8
DelayedJob ActiveRecord v4.1.4
MySQL
code:ruby
class MyJob < ApplicationJob
queue_as :default
retry_on StandardError
def perform(model)
$stderr.puts model.inspect
raise
end
end
code:shell
% ./bin/rails runner "MyJob.perform_now(12345)"
12345
で、その後Active Jobのコンソールに12345が何回も表示される。(無限に続く雰囲気)
入れ子にしてみる
code:ruby
class MyJob < ApplicationJob
queue_as :default
retry_on StandardError, wait: 3.seconds, attempts: 3 do |job, error|
$stderr.puts "retry_on block"
end
def perform(model)
$stderr.puts model.inspect
ret = MySubJob.perform_now
end
end
class MySubJob < ApplicationJob
queue_as :default
def perform
$stderr.puts self.class
raise
end
end
code:shell
% ./bin/rails runner "MyJob.perform_now(12345)"
12345
MySubJob
subjob valueは出力されない。
で、Active Jobのログには
code:text
12345
MySubJob
12345
MySubJob
retry_on block
と二回表示される
attemps: 3は、最初のperform_nowでの一回+リトライ二回で消費されたということなのかな。
この時点でジョブキューからジョブは消えてる。
サブジョブの方でリトライ設定をする
code:ruby
class MyJob < ApplicationJob
queue_as :default
def perform(model)
$stderr.puts model.inspect
ret = MySubJob.perform_now
end
end
class MySubJob < ApplicationJob
queue_as :default
retry_on StandardError, wait: 3.seconds, attempts: 3 do |job, error|
$stderr.puts "retry_on block"
end
def perform
$stderr.puts self.class
raise
end
end
code:shell
% ./bin/rails runner "MyJob.perform_now(12345)"
12345
MySubJob
subjob value: RuntimeError
Acitive Jobログ:
code:text
MySubJob
MySubJob
retry_on block
親ジョブにはエラーオブジェクトが返されるんだね。
つまりサブジョブの最終的な成功・失敗を補足できない
以下のような場合はretry_onに頼るのでなく、rescue_fromを使って自分でカスタマイズする必要がある
要求
サブジョブが複数あって、
それぞれでwaitやattemptsが違う、というようなことをやりたくて、
且つ親ジョブでサブジョブの成功・失敗を補足したい
こういう条件の時には、親ジョブを使ってサブジョブをperform_nowするのでなく、各サブジョブの終わりに、次のサブジョブをエンキューするという処理を入れるほうがいいかも