[rails]whenever設定時にSettingsを呼びだそうとしたらハマった(capistrano)
cron設定を管理するのに便利なgemといえば wheneverですね。
今回、whenever使用時にconfig/schedule.rb内で定数管理gem( rails_config)を呼びだそうとしたところエラーが発生しかなりハマりました。
環境に応じてschedule.rbの内容を切り替えたい、という場合が今後もありそうなので対応策をメモしておきます。
rails_configを使う前の設定
最初はSettingsを使っておらず、以下のような sitemap_generatorの更新処理を書いていてこれは問題ありませんでした。
# config/schedule.rb
rails_env = ENV['RAILS_ENV'] || :production
set :environment, rails_env
every 1.day, :at => '5:00 am' do
rake "-s sitemap:refresh"
end
set :environmentを環境ごとに指定しておくことで、wheneverが以下のようにRAILS_ENVを自動補完してくれます。
RAILS_ENV=production bundle exec rake -s sitemap:refresh --silent
rails_configを呼びだそうとしてハマった
上記の設定に加えて定期的にバッチのURLにアクセスする設定を追加しました。
バッチURLは自分自身からのアクセス以外は無視するIP制限をかけてあるものとします。
# config/schedule.rb
rails_env = ENV['RAILS_ENV'] || :production
set :environment, rails_env
every 1.day, :at => '5:00 am' do
rake "-s sitemap:refresh"
end
every 1.day, :at => '0:00 am' do
command "wget --spider http://#{Settings.host}/batch/test"
end
そのまま bundle exec whenever で設定を確認しようとしたところ、 uninitialized constant エラーが発生。
Rails設定を呼び出すには、schedule.rb内に
require File.expand_path(File.dirname(__FILE__) + "/environment")
を記述しておく必要がありました。
というわけで
# config/schedule.rb
ENV['RAILS_ENV'] ||= 'production'
require File.expand_path(File.dirname(__FILE__) + "/environment") # 追加
set :environment, ENV['RAILS_ENV']
every 1.day, :at => '5:00 am' do
rake "-s sitemap:refresh"
end
every 1.day, :at => '0:00 am' do
command "wget --spider http://#{Settings.host}/batch/test"
end
これで手動実行すれば問題なく実行できました。
が、capistrano経由で反映する際にうまくいかず更にハマりました。
capistrano(v3)設定
最初は以下のように設定していたのですが、これだとRAILS_ENVが指定されていないため、デフォルトのdevelopmentでwheneverを実行しようとするためエラーになってしまいました。
set :whenever_roles, 'batch'
set :whenever_identifier, ->{ "#{fetch(:application)}_#{fetch(:stage)}" }
そこで、色々試行錯誤しつつ、最終的にはwheneverのソースコードを見ながら
set :whenever_roles, 'batch'
set :whenever_identifier, ->{ "#{fetch(:application)}_#{fetch(:stage)}" }
set :whenever_command, -> { ["RAILS_ENV=#{fetch(:stage)}", :bundle, :exec, :whenever] } # これを追加
を指定したところ、うまく実行できました。
これでdeploy実行時にbatchロールのサーバにwhenever設定が適用されます。
whenever設定のみ更新したい場合は以下のタスクでできます。
# cron設定更新
cap production whenever:update_crontab
# cron設定解除
cap production whenever:clear_crontab
これはハマりました。
参考
- [Wheneverは導入が超簡単なcrontab管理ライブラリGemです![Rails4.1] - 酒と泪とRubyとRailsと](http://morizyun.github.io/blog/whenever-gem-rails-ruby-capistrano/)