LoginSignup
1
1

More than 5 years have passed since last update.

Resque.inline と例外処理の落とし穴

Posted at

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

:point_up: のようなコードがあるとすると、

  • Resque.inline == false の場合、 {"success":1}という application/json なレスポンスが返る。ジョブは RuntimeError が発生して失敗し、 Failed Jobs に入る。
  • Resque.inline == true の場合、 RuntimeError がトップレベルまで伝播してしまい、 application/json なレスポンスは返らない。

development モードのときに Resque.inline を有効にしていたりすると、 production では不要な begin ... rescue ... endResque.enqueue の部分を囲ってやったりする必要が出てくる。

Resque は「例外が発生したら Job を Failed とみなす」というポリシーのようなので、例外の発生を抑制しつつ Failed にするのはちょっと難しそう(やり方は調べてません)つまり、ジョブを enqueue する側に(本来不要な)例外の捕捉処理を仕込むか、ジョブを fail させるのを諦める必要がでてくる。どちらも不自然。

なので、結論として、 Resque.inline は避けたほうがよさそう。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1