Job, Active Job, Delayed Jobとは
Job
メールの送信、データのインポート/エクスポートなどの時間のかかる処理を、適した方法でバックエンドで行うためのコンセプト。
Active Job
Sidekiq, Resque, Delayed Jobといった実際にバックグラウンドでジョブを実行するgemの差分をほぼ意識しないでジョブを扱えるようにするための、ジョブのインフラ。
Delayed Job
上記のバックエンド処理を行うために使われるメジャーなgemの一つ。(他のgemとの比較記事: http://qa.atmarkit.co.jp/q/2406)
具体例から見るメリット
例: メール送信
####◯ Jobを使わずに、メール送信(deliver)を行う場合
...
def deliver
@email = Email.find(params[:id])
@email.deliver #deliverというインスタンスメソッドで送信できるとする。
redirect_to complete_email_url
end
...
こんな感じで、redirectするまでに、メールがdelverされるのを待つ必要がある。
####◯ Delayed Jobを使う
# Controller(その場)で実行
@email.deliver
# Job(バックエンド)に委託する
@email.delay.deliver
この一部分を上記のように、変更すると、controller上では、バックエンドに委託したら先にいけるので、サクッと次のredirectの処理までいける!userを待たせなくて良い!という。Delayed Jobを使うと書き方もシンプルで便利っすね〜。
####◯ Active Jobと連携して使う
As I mentioned, Active Jobは、実はgemたちの後から、Railsに導入されたgemごとの操作方法を統一できるJobのインフラ。ここでは、その統一された方法で、Delayed Jobを扱うこと方法を考える。
- アプリ側で時間のかかる処理を、それぞれのJob Classを定義してそちらに移行。
- アプリ側から、そのJob Classを呼び出す。
# Job Classの定義
class EmailDeliverJob < ActiveJob::Base
queue_as :default
def perform(email_id)
# controller(アプリ側)で行っていた処理(以下)が移動された
Email.find(email_id).deliver
end
end
# controller(アプリ側)でEmailDeliverJob(定義したJobClass)を呼び出す
...
def deliver
EmailDeliverJob.perform_later(params[:id])
redirect_to complete_email_url
end
..
これで、先ほど同様、バックエンドに重い処理任せてcontrollerは先に進めるというわけですね。
これまで見てきた、重い処理をJobに委託することを、"Jobを登録する(enqueue)"という。
Active Jobと連携するときにしなくてはいけない細かい設定たち
- どのgemを使うのかアプリに教える
...
config.active_job.queue_adapter = :delayed_job
...
- Jobの作成
以下のコマンドでJob作成。
rails g job EmailDeliver
作成されるapp/jobs/email_deliver_job.rbが先ほど出てきたJob Classの記述を持つ。
使い方 3ステップ
1. DelayedJob(gem)のインストール
# Gemfileに。
gem 'delayed_job_active_record'
# で、インストール
bundle install
Jobを管理するテーブルを作成する。
rails g delayed_job:active_record
rake db:migrate
2.ジョブを登録する(enqueue)
"具体例からみるメリット"を参照。
3.Jobを実行する(workerの起動)
rake taskでworkerを起動し、Jobを処理する。これが起動されるまでは、Jobは処理されないので要注意。委託業者を起動させる感じだね。
rake jobs:work
(本番時は、daemonsというgemでworkerを走らせる。https://github.com/ghazel/daemons)
応用
- コールバックを使う(http://railsguides.jp/active_job_basics.html)
Jobのenqueue前後、perform前後などに行うlogicを指定できる。 - その他もありそう。参照先をよく読むとありそう。
参照先
- http://qiita.com/ryohashimoto/items/2f8fd685920a5318def4#%E3%82%B8%E3%83%A7%E3%83%96%E3%81%AE%E5%AE%9F%E8%A1%8C
- http://railsguides.jp/active_job_basics.htmlhttp://railsguides.jp/active_job_basics.html
- https://github.com/collectiveidea/delayed_job
- http://ruby-rails.hatenadiary.com/entry/20150304/1425396671
- http://qa.atmarkit.co.jp/q/2406
- https://github.com/ghazel/daemons