Railsでdelayed_jobを利用する場合の手順メモ。Railsのバージョンは2.2.2。
Rails2系でのdelayed_jobはrubygemsの依存関係を見ると2.3以上は2.0.7、それ以下は2.0.6となっているが、Rails 2.2.2で2.0.6は
script/generate delayed_job
Couldn't find 'delayed_job' generator
となってgeneratorが作れないので、2.0.4を使用した。Couldn't find 'delayed_job' generator
ちなみに、delayed_jobのオリジナルはhttps://github.com/tobi/delayed_jobらしいが、メンテされていて高機能な
https://github.com/collectiveidea/delayed_job
を使用する。
参考:https://github.com/collectiveidea/delayed_job/tree/v2.0.4
■インストール
gem install delayed_job -v 2.0.4
■config/environment.rbを編集
config.gem 'delayed_job'
■Rakefileの編集
Rake taskはgemから自動でロードされるのでRakefileを以下のように編集
begin
gem 'delayed_job'
require 'delayed/tasks'
rescue LoadError
STDERR.puts "Run `rake gems:install` to install delayed_job"
end
■マイグレーション
script/generate delayed_job
rake db:migrate
#テストDB
rake db:test:prepare
rake db:migrate
#テストDB
rake db:test:prepare
■delayed_jobで非同期に実行
#通常の場合
Notifier.deliver_signup(@user)
# delayed_jobで非同期に実行
Notifier.delay.deliver_signup @user
Notifier.deliver_signup(@user)
# delayed_jobで非同期に実行
Notifier.delay.deliver_signup @user
毎回delayed_jobで実行する場合はhandle_asynchronouslyをメソッドの後で宣言する
class Mailerhandle_asynchronouslyは様々なオプションを追加でき、Procオブジェクトを渡すと実行までの時間などを設定可能。
def deliver
# long running method
end
handle_asynchronously :deliver
end
5分後に実行する場合
handle_asynchronously :deliver, :run_at => Proc.new { 5.minutes.from_now }
■ジョブの実行
$ RAILS_ENV=production script/delayed_job start
$ RAILS_ENV=production script/delayed_job stop
$ RAILS_ENV=production script/delayed_job stop
Capistranoのレシピ。
■Capistranoのdeploy:rb
#delayed_job
after "deploy:stop", "delayed_job:stop"
after "deploy:start", "delayed_job:start"
after "deploy:restart", "delayed_job:restart"
namespace :delayed_job do
def rails_env
fetch(:rails_env, false) ? "RAILS_ENV=#{fetch(:rails_env)}" : ''
end
def args
fetch(:delayed_job_args, "")
end
desc "Stop the delayed_job process"
task :stop, :roles => :app do
run "cd #{current_path};#{rails_env} script/delayed_job stop"
end
desc "Start the delayed_job process"
task :start, :roles => :app do
run "cd #{current_path};#{rails_env} script/delayed_job start #{args}"
end
desc "Restart the delayed_job process"
task :restart, :roles => :app do
run "cd #{current_path};#{rails_env} script/delayed_job restart #{args}"
end
end
■ジョブキューを全て実行
rake jobs:work
■実行のオプションを指定するにはconfig/initializers/delayed_job_config.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::Worker.sleep_delay = 60
Delayed::Worker.max_attempts = 3
Delayed::Worker.max_run_time = 5.minutes
■Rspecで非同期をオフにする
いくつか方法があるようだが、1以外はエラーが出た。2.0.4以上なら使えるのかもしれない。
□1 _without_delayをつけてコールする
deliver_without_delay
□2 Delayed::Worker.new.work_offをメソッドコール後に追加する
Mailer
def deliver
# long running method
end
handle_asynchronously :deliver
end
describe Mailer
context "#deliver" do
before do
@person = Person.new
@person.deliver
Delayed::Worker.new.work_off
end
・
・
・
end
end
□3 environment/productionだけ非同期に実行するメソッドを設定する
# config/environments/production.rb
Mailer.handle_asynchronously :deliver
タグ:Rails delayed_job