genonymous

GenestreamのTechブログ

Rails4.2のActive Jobを使って非同期に処理を実行したりメールを送信してみる

こんにちは徳山です。今回はRails4.2の新機能のActive Jobを軽く使ってみたので共有します。

Active Jobとは

  • Rails 4.2から導入されたキューイングの為の仕組み
  • 実際のキューイングはDelayed Job, Resque, Sidekiqなどを使い各キューイングシステムとのアダプターになる
  • バックグラウンドで使うキューイングシステムが何であれ同じように書け、移行コストも下がる
  • Action Mailerも内部で使うようになった
  • ビルドインアダプタは9つ 参考 : Active Job adapters

試しに与えれたメッセージをログに出力するだけのタスクを色々な方法で実行してみます。

今までのDelayed Jobを使った書き方

必要なGemのインストールする

gem "delayed_job"
gem "delayed_job_active_record"

Delayed Jobのキュー保存用のテーブルを作成します。

rails generate delayed_job:active_record
rake db:migrate

Delayed Job workerの起動

rake jobs:work

非同期で実行したいタスクを作成する

class Task
  def exec message
      Rails.logger.info(message)
  end
end

タスクを実行する

Task.new.exec '普通に実行'
Task.new.delay.exec 'Active Jobを使わずに非同期で実行'
Task.new.delay(run_at: 30.seconds.from_now).exec '30秒後にActive Jobを使わずに非同期で実行'

Active Jobを使って書いてみる

Rails 4.2.0をインストールする

gem 'rails', '4.2.0'

application.rbにAdapterの設定を追加する

config.active_job.queue_adapter = :delayed_job

Jobを作成

rails generate job Sample

これで app/jobs/sample_job.rb が生成されます。 受け取ったメッセージをそのままタスクに渡す処理を書きます。

class SampleJob < ActiveJob::Base
  queue_as :default

  def perform(message)
    Task.new.exec(message)
  end
end

Jobの呼び出し

SampleJob.perform_later 'Active Jobを使って非同期で実行'
SampleJob.set(wait: 30.second).perform_later 'Active Jobを使って30秒後に非同期で実行'

Action Mailerを使ったメール送信

  • deliverメソッドはdeplicatedになった(deliver_nowのプレフィックス)
  • deliver_nowを使う
  • deliver_laterは内部でActive Jobを使っているので非同期になる

参考 : ActionMailer::MessageDelivery

MyMailer.confirm(@user).deliver_now
MyMailer.confirm(@user).deliver_later
MyMailer.confirm(@user).deliver_later(wait: 30.second) #30秒後に送信

以上です!