Rails3でdelayed_jobを使って、非同期処理を行う
collectiveidea/delayed_job · GitHub
delayed_jobはHerokuでも使えるみたいなので、Rails3で動かしてみました。
簡単な設定だけで、非同期処理が実装できます。
今回はメール送信する部分を非同期にしてみました。
Gemfile
gem 'delayed_job'
この一行を追加します。
$ bundle install
gemをインストールします。
begin require 'delayed/tasks' rescue LoadError STDERR.puts "Run `rake gems:install` to install delayed_job" end
これでdelayed_jobのrakeタスクを使えるようになります。
config/initializers/delayed_job.rb
Delayed::Worker.destroy_failed_jobs = false Delayed::Worker.sleep_delay = 60 Delayed::Worker.max_attempts = 3 Delayed::Worker.max_run_time = 5.minutes
delayed_jobの設定をします。
db/migrate/20100909011916_create_delayed_jobs.rb
class CreateDelayedJobs < ActiveRecord::Migration def self.up create_table :delayed_jobs, :force => true do |table| table.integer :priority, :default => 0 # Allows some jobs to jump to the front of the queue table.integer :attempts, :default => 0 # Provides for retries, but still fail eventually. table.text :handler # YAML-encoded string of the object that will do work table.text :last_error # reason for last failure (See Note below) table.datetime :run_at # When to run. Could be Time.zone.now for immediately, or sometime in the future. table.datetime :locked_at # Set when a client is working on this object table.datetime :failed_at # Set when all retries have failed (actually, by default, the record is deleted instead) table.string :locked_by # Who is working on this object (if locked) table.timestamps end add_index :delayed_jobs, [:priority, :run_at], :name => 'delayed_jobs_priority' end def self.down drop_table :delayed_jobs end end
「rails g migration create_delayed_jobs」でマイグレーションファイルを作成します。
※Rails3は「ruby script/generate delayed_job」が使えませんでした。
$ rake db:migrate
マイグレートを実行します。
あとは、アプリ側のメール送信部分を以下のように修正して
「rake jobs:work」を別プロセスで起動しておけば完了です。
とっても簡単!!
# 修正前 @user.deliver_activation_confirmation! # 修正後 @user.send_later(:deliver_activation_confirmation!)