Resque にはワーカープロセスを別途立ち上げなくても動作する inline モードがある。
Also, you could disable jobs queueing by setting 'inline' attribute. For example, if you want to run all jobs in the same process for cucumber, try:
Resque.inline = ENV['RAILS_ENV'] == "cucumber"
しかし inline モードは例外処理と相性が悪い。ワーカークラスの .perform
メソッド内で例外を送出すると、呼び出し元まで例外が伝播してしまう。 Rails コントローラーのアクションメソッド内から enqueue
する場合などに困ったことになる。
class MyController < ApplicationController
def some_action
if @model.save
Resque.enqueue MyWorker, @model.id
render json: {success: 1}
else
render json: {success: 0, message: "oops"}
end
end
end
class MyWorker
@queue = :my_worker
def self.perform(id)
puts id
raise RuntimeError, "oops"
end
end
のようなコードがあるとすると、
-
Resque.inline == false
の場合、{"success":1}
というapplication/json
なレスポンスが返る。ジョブは RuntimeError が発生して失敗し、 Failed Jobs に入る。 -
Resque.inline == true
の場合、 RuntimeError がトップレベルまで伝播してしまい、application/json
なレスポンスは返らない。
development モードのときに Resque.inline
を有効にしていたりすると、 production では不要な begin ... rescue ... end
で Resque.enqueue
の部分を囲ってやったりする必要が出てくる。
Resque は「例外が発生したら Job を Failed とみなす」というポリシーのようなので、例外の発生を抑制しつつ Failed にするのはちょっと難しそう(やり方は調べてません)つまり、ジョブを enqueue する側に(本来不要な)例外の捕捉処理を仕込むか、ジョブを fail させるのを諦める必要がでてくる。どちらも不自然。
なので、結論として、 Resque.inline
は避けたほうがよさそう。