There's an echo in my head

日々のメモ。

delayed_job + Rails4 + Capistrano + rbenv

Rails 4(ActiveRecord)でdelayed_jobを使いつつ、それをCapistranoでデプロイする方法のメモ。基本的に本家のWikiに従う。

キューの機能を使う

まず必要なgemをインストールしてマイグレーションファイルと実行ファイルを作成する。

# Gemfile
gem "delayed_job"
gem "delayed_job_active_record"
gem "daemons" # デプロイ先でデーモンとして動かすのに必要
$ bundle install
$ bundle exec rails g delayed_job:active_record
$ bundle exec rake db:migrate

実行ファイルはbin/delayed_jobに作成される。Rails3以前はscript/delayed_jobに作られていたので要注意。

ワーカーはrakeタスクで手軽に起動できる。

$ bundle exec rake jobs:work

キューに入れたいメソッドは次のようにdelayedを挟んで呼び出す。 *1

SomeClass.delayed.some_method(args)

デプロイする

デプロイ先でdelayed_jobを動かすにはちょっと設定が必要。

# config/deploy.rb
require "delayed/recipes"

role :delayed_job, 'delayed_job.example.com' # ワーカ用サーバの指定
set :delayed_job_server_role, :delayed_job   # delayed_jobのワーカを動かすロール名の設定
set :delayed_job_command, defer { "#{bundle_cmd} exec bin/delayed_job" }

after "deploy:stop",    "delayed_job:stop"
after "deploy:start",   "delayed_job:start"
after "deploy:restart", "delayed_job:restart"

:delayed_job_commandはぱっと見Wikiに載ってなかったのでメモ。

  • :delayed_job_commandはデフォルトだとscript/delayed_jobになるけれど、前述したとおりRails4では実行ファイルはbin/delayed_jobになる。
  • さらにcapistrano/bundlerやcapistrano-rbenvによるパスの設定を適用するため、bundle_cmdのもとで実行させる。ただしこれはタスク実行時に決定されるものなので、deferを使って決定を遅延させておく。

これでbundle exec cap deployすれば、適宜ワーカが起動・再起動するようになる。

書いて気づいたけど、rbenv要素がなかった…。これもcapistrano-rbenvがうまくbundle_cmdを書き換えてくれてるおかけ。

*1:普通ワーカーはクラスで呼び出すけど、そういえばインスタンスに対しても呼び出せるのかな?未検証

このブログに出てくるコードスニペッツは、引用あるいは断りがない限りMITライセンスです。